<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    
    <title>The Blue Book</title>
    <description>My personal digital garden</description>
    <link>https://lyz-code.github.io/blue-book</link>
    <atom:link href="https://lyz-code.github.io/blue-book/yearly.xml" rel="self" type="application/rss+xml"/>

    
    <managingEditor>Lyz</managingEditor>

    
    <pubDate>2026-01-01 07:00:46+00:00</pubDate>
    <ttl>525600</ttl>

    
    <generator>mkdocs-newsletter - v1.1.0</generator>

    
    
    <image><url>https://lyz-code.github.io/blue-book/img/logo.bmp</url><title>The Blue Book</title>
      <link>https://lyz-code.github.io/blue-book</link>
    </image>
    

    
    
    <item><title>2025</title>
      <author>Lyz</author>
      <description>&lt;article class=&#34;md-content__inner md-typeset&#34;&gt;  &lt;h2 id=&#34;militancy&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/activism/&#34;&gt;Militancy&lt;/a&gt;&lt;/h2&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/activism/#references&#34;&gt;Add 38c3 talk on state of surveillance.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://media.ccc.de/v/38c3-state-of-surveillance-a-year-of-digital-threats-to-civil-society&#34;&gt;38C3 Talk: State of Surveillance: A year of digital threats to civil society&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/anticolonialism/#anticolonialism-in-technology&#34;&gt;Anticolonialism in technology.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Art&lt;/strong&gt; - &lt;a href=&#34;https://ail.angewandte.at/explore/decolonizing-technology/&#34;&gt;Decolonizing technology&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Articles&lt;/strong&gt; - &lt;a href=&#34;https://jipel.law.nyu.edu/shanzhai-an-opportunity-to-decolonize-technology/&#34;&gt;Shanzhai: An Opportunity to Decolonize Technology? by Sherry Liao&lt;/a&gt; - &lt;a href=&#34;https://alasbarricadas.org/forums/viewtopic.php?t=9654&#34;&gt;Técnicas autoritarias y técnicas democráticas by Lewis Mumford&lt;/a&gt; (&lt;a href=&#34;https://istas.net/descargas/escorial04/material/dc05.pdf&#34;&gt;pdf&lt;/a&gt;)&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Books&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.ruhabenjamin.com/race-after-technology&#34;&gt;Race after technology by Ruha Benjamin&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.goodreads.com/book/show/62790909-the-palestine-laboratory&#34;&gt;The Palestine Laboratory: How Israel Exports the Technology of Occupation Around the World by Antony Loewenstein&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Frantz_Fanon&#34;&gt;Frantz Fanon books&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.agenziax.it/hacking-del-se&#34;&gt;Hacking del sé by Ippolita&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.eleuthera.it/materiale.php?op=2699&#34;&gt;Tecnologie conviviali by Carlo Milani&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://vision.centroculturadigital.mx/media/done/descolonizarYD.pdf&#34;&gt;Descolonizar y despatriarcalizar las tecnologías by Paola Ricaurte Quijano&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Research&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://researchmethodscommunity.sagepub.com/blog/decolonization-indigenous-methods-technology&#34;&gt;Decolonization, Technology, and Online Research by Janet Salmons&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Talks&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://re-publica.com/de/session/decolonize-tech-how-design-all&#34;&gt;re:publica 2024: Christoph Hassler - Decolonize Tech&lt;/a&gt; (&lt;a href=&#34;https://www.youtube.com/watch?v=R10Dwgxt_mg&#34;&gt;video&lt;/a&gt;)&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Añadir poema sobre la falta de acción.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://es.wikipedia.org/wiki/Primero_se_llevaron...&#34;&gt;Maravilloso poema de alemán Martin Niemöller&lt;/a&gt; sobre la cobardía de los intelectuales alemanes tras el ascenso de los nazis al poder y la subsiguiente purga de sus objetivos escogidos, grupo tras grupo.&lt;/p&gt;  &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/activism/#apps-para-no-saltarte-el-boycott&#34;&gt;Apps para no saltarte el boycott.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://play.google.com/store/apps/details?id=com.bashsoftware.boycott&amp;amp;hl=en-US&#34;&gt;No Thanks&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Oslo advertisement on the importance of the symbols.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://bsky.app/profile/javiermarin.com/post/3lqhdlafjf22k&#34;&gt;link&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/activism/#references&#34;&gt;Añadir pantube.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://pantube.tv/&#34;&gt;Pantube&lt;/a&gt;: YouTube de izquierdas&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/activism/#references&#34;&gt;Add rich don&#39;t work representation.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://therichdont.work&#34;&gt;The rich don&#39;t work&lt;/a&gt;: game to get a grasp of how much money they make without doing anything&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/activism/#podcasts&#34;&gt;Añadir podcast sobre la Operación Gladio.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.podtrac.com/pts/redirect.mp3/pdst.fm/e/chrt.fm/track/B1992E/traffic.megaphone.fm/EOM2231294568.mp3?updated=1727251558&#34;&gt;No es el fin del mundo: 46. ¿Qué fue la Operación Gladio?&lt;/a&gt;: Para pasárselo a cualquier persona reformista&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Añadir vídeos de David zona zero.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://bsky.app/profile/davidzonazero.bsky.social/post/3lz6p4tmvos2r&#34;&gt;David zona zero y los distintos barrios&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;antifascism&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/antifascism/&#34;&gt;Antifascism&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Añadir un par de artículos interestantes.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.newsweek.com/hitler-incompetent-lazy-nazi-government-clown-show-opinion-1408136&#34;&gt;Hitler Was Incompetent and Lazy—and His Nazi Government Was an Absolute Clown Show&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://awards.journalists.org/entries/open-source-extremist-identifications/&#34;&gt;Bellincat Open-Source Extremist Identifications&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Añadir web sistemapunk.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://sistemapunk.com&#34;&gt;Sistemapunk&lt;/a&gt;: hace investigaciones sobre grupos nazis&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;hacktivism&#34;&gt;Hacktivism&lt;/h3&gt; &lt;h4 id=&#34;mobile-verification-toolkit&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/mobile_verification_toolkit/&#34;&gt;Mobile Verification Toolkit&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Chaos feminist convention.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;events.haecksen.org/cfc25&#34;&gt;Chaos feminist convention&lt;/a&gt; (looks like it will be mostly in german)&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add 38C3 talk from pegasus to predator.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://media.ccc.de/v/38c3-from-pegasus-to-predator-the-evolution-of-commercial-spyware-on-ios&#34;&gt;38C3 talk: From Pegasus to Predator - The evolution of Commercial Spyware on iOS&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/mobile_verification_toolkit/#other-tools-for-similar-purpose&#34;&gt;Other tools for similar purpose.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.eff.org/deeplinks/2025/03/meet-rayhunter-new-open-source-tool-eff-detect-cellular-spying&#34;&gt;Rayhunter&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;collectives&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/ccc/&#34;&gt;Collectives&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ccc/#remember-these-useful-things&#34;&gt;Remember these useful things.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Use c3lingo for german talks&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;There are many talks in german, this may deter you from attending them, but don&#39;t worry, if they are hosted in the main tracks you can hear the translation in english live.&lt;/p&gt; &lt;p&gt;You can access them &lt;a href=&#34;https://c3lingo.org/&#34;&gt;here&lt;/a&gt;, they work best with the ccc wifi.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://events.ccc.de/congress/2024/infos/mentors.html&#34;&gt;Chaos mentors&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;At Chaos Mentors, they connect experienced mentors with first-time visitors of Congress. Their goal is to make Congress more inclusive by supporting those who might not usually attend, including people with special needs.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ccc/#first-time-angel-tips&#34;&gt;First time angel tips.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you&#39;re lost on what shifts you might want to take here is the ones I&#39;ve found easy to do: - Talk access shifts: You will be on the access of the talks making sure that the doors are opened and closed when it should and that people do not linger in the corridors, whenever you want to see a talk in one of the main tracks take these shifts as you&#39;ll be able to watch it fine and also help the organisation. If you know for sure you&#39;ll be attending one of these talks, reserve the shift the day before as they usually fly away soon. - Standby angel: You just stay in heaven for a couple of hours waiting for someone to tell you what you need to do. It&#39;s a good shift to know people and to find your place in heaven. If you know for sure you&#39;ll have a free slot between talks and workshops, reserve the shift the day before as they usually fly away soon. - At teardown: If you can stay after the congress has ended, help in the tear down, I first go to the assemblies that have attracted me the most and then go to heaven to see what else is needed.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add critical switch.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://critical-switch.org/&#34;&gt;Critical Switch&lt;/a&gt;: una colectiva transhackfeminista no mixta1 interesades en la cultura libre, la privacidad y la seguridad digital. Promovemos la cultura de la seguridad para generar espacios más seguros en los movimientos sociales y activistas.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add méxico collectives.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://sursiendo.org/quienes-somos/&#34;&gt;Sursiendo&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://tecnoafecciones.net&#34;&gt;Tecnoafecciones&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;anticapacitismo&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/anticapacitismo/&#34;&gt;Anticapacitismo&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Añadir proyecto artefactos.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.artefactos.org&#34;&gt;https://www.artefactos.org&lt;/a&gt;: son gente de tecnología y familias de críos con distintas necesidades, colaborando juntos. Hacen prototipos en 3D que te puedes imprimir&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;feminism&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/feminism/&#34;&gt;Feminism&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/feminism/#references&#34;&gt;New References.&lt;/a&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/feminism/#references&#34;&gt;Add good movies and tv shows to discuss practical feminism with teenagers and adults.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.themoviedb.org/tv/249042-adolescence&#34;&gt;Adolescence (TV Series 2025-2025)&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.themoviedb.org/movie/1075175-how-to-have-sex&#34;&gt;How to Have Sex (2023)&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;palestine&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/palestine/&#34;&gt;Palestine&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/palestine/#al-jazeera-documenaries&#34;&gt;Add Al Jazeera documenaries.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;A la luz de los acontecimientos actuales en Palestina, un gran número de cineastas han puesto sus películas sobre Palestina a disposición en línea de forma gratuita.&lt;/p&gt; &lt;p&gt;Están en árabe y no tienen subtítulos así que no se puede bajar, pero si se pueden ver directamente en youtube con los subtítulos autogenerados.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Una colección de documentales publicada por Al Jazeera Documentary: &lt;a href=&#34;https://bit.ly/3yp2nBI&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;https://bit.ly/2SSpMeC&#34;&gt;2&lt;/a&gt;, &lt;a href=&#34;https://bit.ly/3f0KK3P&#34;&gt;3&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/eywuYeflWzg&#34;&gt;El documental &#34;Guardián de la memoria&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/an4hRFWOSQQ&#34;&gt;El documental &#34;Un asiento vacío&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/wqSmdZy-Xcg&#34;&gt;El documental &#34;El piloto de la resistencia&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://vimeo.com/499672067&#34;&gt;El documental &#34;Jenin&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://vimeo.com/432062498&#34;&gt;El documental &#34;El olivo&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/1JlIwmnYnlE&#34;&gt;El documental &#34;Escenas de la ocupación en Gaza 1973&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/HnZSaKYmP2s&#34;&gt;El documental &#34;Gaza lucha por la libertad&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/cQZiHgbBBcI&#34;&gt;El documental &#34;Los hijos de Arna&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://vimeo.com/209189656/e5510a6064&#34;&gt;El cortometraje &#34;Strawberry&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/fgcIVhNvsII&#34;&gt;El cortometraje &#34;The Place&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/aDvOnhssTcc&#34;&gt;El documental &#34;El alcalde&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/Bwy-Rf15UIs&#34;&gt;El documental &#34;La creación y la Nakba 1948&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/C56QcWOGSKk&#34;&gt;El documental &#34;Ocupación 101&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://vimeo.com/220119035&#34;&gt;El documental &#34;La sombra de la ausencia&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/2WZ_7Z6vbsg&#34;&gt;El documental &#34;Los que no existen&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://vimeo.com/220116068&#34;&gt;El documental &#34;Como dijo el poeta&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/TZU9hYIgXZw&#34;&gt;El documental &#34;Cinco cámaras rotas&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://vimeo.com/510883804&#34;&gt;El largometraje &#34;Paradise Now&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/I--r85cOoXM&#34;&gt;El cortometraje &#34;Abnadam&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/dYMQw7hQI1U&#34;&gt;El largometraje &#34;Bodas de Galilea&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://vimeo.com/780695653&#34;&gt;El largometraje &#34;Kofia&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/hHFlWE3N9Ik&#34;&gt;El largometraje documental &#34;Slingshot Hip Hop&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/Ma8H3sEbqtI&#34;&gt;El largometraje documental &#34;Tel Al-Zaatar&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/Ma8H3sEbqtI&#34;&gt;El largometraje documental &#34;Tal al-Zaatar - Detrás de la batalla&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/htJ10ACWQJM&#34;&gt;El documental &#34;In the Grip of the Resistance&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/gMk-Zi9vTGs&#34;&gt;El documental &#34;Swings&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/Y31yUi4WVsU&#34;&gt;El documental &#34;Naji al-Ali es un artista visionario&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://vimeo.com/433362585&#34;&gt;El documental &#34;La puerta superior&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://vimeo.com/184213685?1&#34;&gt;El largometraje documental &#34;En busca de Palestina&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://bit.ly/3c10G3Z&#34;&gt;El largometraje &#34;La sal de este mar&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/wdkoxBjKM1Q&#34;&gt;El largometraje documental &#34;Hakki Ya Bird&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://bit.ly/3bXNAVp&#34;&gt;La serie &#34;Palestina Al-Taghriba&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://bit.ly/3hG8sDV&#34;&gt;La serie &#34;Yo soy Jerusalén&#34;&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;deteccion-de-estupas&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/estupas/&#34;&gt;Detección de estupas&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Malditos estupas.&lt;/p&gt; &lt;p&gt;Los estupas (o infiltrados) son de los peores cuerpos de represión del estado. No sólo porque extraen información de los colectivos sino porque generan un ambiente de desconfianza y miedo que muchas veces es paralizante o incluso desarticula los propios colectivos. De la peor escoria de la sociedad...&lt;/p&gt; &lt;p&gt;Por desgracia, en el estado español &lt;a href=&#34;https://www.elsaltodiario.com/montajes-policiales&#34;&gt;está bastante de moda&lt;/a&gt;. Por suerte no estamos desamparadas, varias compañeras están generando materiales para familiarizarnos con este problema. Desde el documental &lt;a href=&#34;https://www.3cat.cat/3cat/infiltrats/video/6319194/&#34;&gt;Infiltrats&lt;/a&gt; hasta el &lt;a href=&#34;https://doscuadrados.es/colaboraciones.html&#34;&gt;Manual para destapar a un infiltrado&lt;/a&gt; (puedes ver &lt;a href=&#34;https://www.elsaltodiario.com/represion/manual-infiltrado-policial-espionaje-policia-directa&#34;&gt;el artículo del salto sobre el manual&lt;/a&gt;).&lt;/p&gt; &lt;p&gt;Probablemente estos desgraciados adaptarán sus modos de hacer para pasar estas detecciones, pero al menos los movimientos sociales ya tenemos una base formal sobre la que trabajar.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Referencias&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://doscuadrados.es/colaboraciones.html&#34;&gt;Manual para destapar a un infiltrado&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;conflicto&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/conflicto/&#34;&gt;Conflicto&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Añadir notas sobre el conflicto desde un punto de vista antipunitivista.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Pensamientos sueltos sobre la visión del conflicto desde un punto de vista antipunitivista&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Dejar de ver los conflictos como una batalla, es una oportunidad de transformación&lt;/li&gt; &lt;li&gt;Los conflictos deben de ser resueltos en colectivo siempre que se pueda&lt;/li&gt; &lt;li&gt;Si se veta a un pavo por comportamientos machistas sólo estás trasladando el problema. Seguirá pululando por diferentes colectivos hasta que arraigue en uno más débil y lo torpedeará&lt;/li&gt; &lt;li&gt;Es difícil de ver el límite entre lo terapéutico y lo transformativo&lt;/li&gt; &lt;li&gt;Cuál es la responsabilidad colectiva de la transformación de una persona?&lt;/li&gt; &lt;li&gt;Nos faltan herramientas para:&lt;/li&gt; &lt;li&gt;la gestión de conflictos en general&lt;/li&gt; &lt;li&gt;la gestión de conflictos físicos en particular&lt;/li&gt; &lt;li&gt;el acompañamiento a ambas partes de un conflicto&lt;/li&gt; &lt;li&gt;el acompañamiento a una persona agresora&lt;/li&gt; &lt;li&gt;es todo lo que me produce malestar violencia?&lt;/li&gt; &lt;li&gt;Cada situación es tan particular que los protocolos no sirven. Es mucho mejor someternos en colectivo y a menudo a situaciones de conflicto y generar desde esa práctica las herramientas que nos puedan servir, de manera que en el momento de la verdad salgan de manera intuitiva.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Referencias&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Películas&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Women_Talking_(film)&#34;&gt;Ellas hablan&lt;/a&gt; (&lt;a href=&#34;https://www.youtube.com/watch?v=pD0mFhMqDCE&#34;&gt;trailer&lt;/a&gt;)&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/How_to_Have_Sex&#34;&gt;How to Have Sex&lt;/a&gt; (&lt;a href=&#34;https://www.youtube.com/watch?v=52b7s-diPk8&#34;&gt;trailer&lt;/a&gt;)&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://es.wikipedia.org/wiki/Promising_Young_Woman&#34;&gt;Promising young woman&lt;/a&gt; (&lt;a href=&#34;https://www.youtube.com/watch?v=7i5kiFDunk8&#34;&gt;trailer&lt;/a&gt;)&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Libros&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://traficantes.net/sites/default/files/pdfs/Micropol%C3%ADticas%20de%20los%20grupos-TdS.pdf&#34;&gt;Micropolítica de los grupos&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://hamacaonline.net/media/publicacio/Conflicto-no-es-lo-mismo_dig2024.pdf&#34;&gt;Conflicto no es lo mismo que abuso&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://maryread.es/producto/ofendiditos&#34;&gt;Ofendiditos&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Series&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://dai.ly/x91qoeq&#34;&gt;La Fièvre&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Podcast&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.primaverasound.com/es/radio/shows/ciberlocutorio/ciberlocutorio-el-marido&#34;&gt;El marido (Ciberlocutorio)&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.primaverasound.com/es/radio/shows/ciberlocutorio/ciberlocutorio-el-cancelado&#34;&gt;El cancelado (Ciberlocutorio)&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=p_frBHfk7cc&#34;&gt;Antipunitivismo con Laura Macaya (Sabor a Queer)&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://soundcloud.com/traficantesdesue-os/s5-procesos-restaurativos-feministas-y-sistemicos-con-anna-gali-fil-a-lagulla?in=traficantesdesue-os/sets/curso-me-cuidan-mis-amigas&#34;&gt;Procesos restaurativos, feministas y sistémicos (Fil a l´agulla en el curso de Nociones Comunes &#34;Me cuidan mis amigas&#34;)&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Artículos&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://ctxt.es/es/20220401/Firmas/39365/feminismo-autoorganizacion-barrio-antipunitivismo-comunidades-violencia-machista.htm&#34;&gt;Con penas y sin glorias: reflexiones desde un feminismo antipunitivo y comunitario:&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://ctxt.es/es/20250301/Firmas/48798/Colectivo-Cantoneras-expulsar-agresores-violencia-de-genero-feminismos-justicia-restaurativa-antipunitivismo.htm&#34;&gt;Expulsar a los agresores no reduce necesariamente la violencia:&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.pikaramagazine.com/2024/10/antipunitivismo-remasterizado/&#34;&gt;Antipunitivismo remasterizado&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.pikaramagazine.com/2021/12/reflexiones-sobre-antipunitivismo-en-tiempos-de-violencias/&#34;&gt;Reflexiones sobre antipunitivismo en tiempos de violencias&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.elsaltodiario.com/palabras-en-movimiento/indispuestas-cuando-nadie-quiere-poner-vida-ello&#34;&gt;Indispuestas. Cuando nadie quiere poner la vida en ello&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lavillana.org/la-deriva-neoliberal-de-los-cuidados/&#34;&gt;La deriva neoliberal de los cuidados&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://zonaestrategia.net/justicia-transformativa-del-dicho-al-hecho/&#34;&gt;Justicia transformativa: del dicho al hecho&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.elsaltodiario.com/la-antinorma/malas-victimas-responden&#34;&gt;Las malas víctimas responden&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Otras herramientas&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lacinetika.wordpress.com/comissio-de-genere/&#34;&gt;Guía para la prevención y actuación frente a las violencias patriarcales de la Cinètika.&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.cooperativestreball.coop/sites/default/files/materials/guia_per_a_la_gestio_de_conflictes.pdf&#34;&gt;Guía Fil a l´agulla per a la gestió de conflictes a les cooperatives (en catalan)&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;anarchism&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/anarchism/&#34;&gt;Anarchism&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/anarchism/#anarchism-in-belarus&#34;&gt;Anarchism in Belarus.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://abc-belarus.org/en/main-page/&#34;&gt;Anarchist black cross Belarus&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://bsky.app/profile/bad-immigrant.bsky.social&#34;&gt;Bad immigrant bluesky&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://pramen.io/en/&#34;&gt;Pramen website&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://kolektiva.media/c/pramenby/videos?s=1&#34;&gt;Pramen videos&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;memoria-historica&#34;&gt;Memoria histórica&lt;/h3&gt; &lt;h4 id=&#34;conflicto-vasco&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/conflicto_vasco/&#34;&gt;Conflicto vasco&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Añadir referencias sobre el conflicto vasco.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.deesonosehabla.com/temporada-3/&#34;&gt;Tercera temporada de (de eso no se habla)&lt;/a&gt;: &#34;Se llamaba como&#34; yo es una serie documental sobre la memoria de la niña Begoña Urroz, sobre las cinco décadas de silencio de una familia… Y sobre el ruido que lo rompió.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;laboral&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/laboral/&#34;&gt;Laboral&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/laboral/#references&#34;&gt;Añadir referencia a la novela Tierra de la luz.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://omny.fm/shows/no-hay-negros-en-el-t-bet/episodio-47-luc-a-asu-mbom-o&#34;&gt;No hay negros en el Tíbet: Episodio 47 - Lucía Asué Mbomío&lt;/a&gt;: Presentan la novela &#34;Tierra de la Luz&#34; de Lucía Asué MbomÍo. Un relato que pone el foco en los temporeros del sur que trabajan en los invernaderos en unas condiciones durísimas, y las injusticias que se viven en el campo. Una novela “bajo plásticos”, cargada de emoción, crítica y toques de realismo mágico.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;trabajadoras-del-hogar&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/trabajadoras_del_hogar/&#34;&gt;Trabajadoras del hogar&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introducir investigación sobre las trabajadoras del hogar.&lt;/p&gt; &lt;p&gt;Nota: para nada soy un experto en este tema, estas son las claves que he ido deduciendo a través de hablar del tema con trabajadoras y gestoras. Así que verificar todo antes de tomarlo por verdad!&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Cuidado de personas mayores dependientes&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;El cuidado de las personas mayores es una movida, especialmente cuando empiezan a ser dependientes. Normalmente necesitan cuidados la mayor parte del tiempo del día. Actualmente existen las siguientes opciones para impartir dichos cuidados:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;La red cercana (normalmente las mujeres de la familia) se encargan de dichos cuidados.&lt;/li&gt; &lt;li&gt;Parte o todos los cuidados se externalizan ya sea a una residencia de ancianos, centros de día o contratando a trabajadoras que acuden al hogar.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;En este mundo podrido donde los servicios públicos están siendo desmantelados, la oferta pública de centros de día o residencias es insuficiente y generalmente en manos de políticas incompetentes (nunca olvidemos &lt;a href=&#34;https://www.elsaltodiario.com/residencias-mayores/7291-muertes-explicacion-familiares-residencias-denuncian-ayuso-sigue-bloqueando-verdad&#34;&gt;las 7291 muertes&lt;/a&gt; que pesan sobre los hombros de Ayuso &lt;a href=&#34;https://www.youtube.com/@quietotodoelmundo&#34;&gt;{hija de puta!}&lt;/a&gt;).&lt;/p&gt; &lt;p&gt;Esto sumado a que las mujeres de la familia ahora trabajan y la precarización del sector de las empleadas del hogar hace que (sobre todo peña que tiene pasta) recurra a contratar trabajadoras en régimen de interna.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Trabajo del hogar en régimen de interna&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;En realidad este trabajo es esclavismo encubierto bajo una pátina legal. Aprovechandose de que la profesión está feminizada y generalmente por personas migrantes, se imponen unas condiciones laborales que no cumplen el estatuto de las trabajadoras.&lt;/p&gt; &lt;p&gt;Con un salario que normalmente no supera el mínimo estas trabajadoras:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Trabajan muchas más horas que las 40 a la semana&lt;/li&gt; &lt;li&gt;Hacen trabajos por fuera de su contrato como limpiar la casa o servir la comida.&lt;/li&gt; &lt;li&gt;Se encuentran encerradas en su lugar de trabajo. Incluso cuando &#34;dejan de trabajar&#34; están dentro del control de sus empleadores.&lt;/li&gt; &lt;li&gt;Al encontrarse solas con las personas a las que cuidan, 24 horas al día, es común encontrarse casos de violencia de género. Muchas cuentan testimonios de atrancar la puerta de su cuarto por la noche.&lt;/li&gt; &lt;li&gt;Los espacios que se les ceden (habitaciones o cuartos de baño) no se respetan y generalmente son usados por otras personas de la familia cuando lo desean, arrebatándoles incluso su cuarto propio.&lt;/li&gt; &lt;li&gt;Generalmente tienen unas dos horas al día para librar. Pero generalmente trabajan en barrios muy lejanos de su hogar, con precios y oferta de ocio muy lejana a sus posibilidades, así que normalmente usan esas horas para pasear. En invierno se pone más complicado con el frío y la lluvia.&lt;/li&gt; &lt;li&gt;Las que libran los fines de semana tienen que pagar una habitación o piso que sólo pueden disfrutar unos pocos días a la semana.&lt;/li&gt; &lt;li&gt;Tienen que soportar el maltrato y la tiranía propia de las personas mayores que ya empiezan a perder la cabeza. A esas edades se exacerban el clasismo y el racismo a la vez que desaparecen los mecanismos de control propio y filtro. Lo que genera situaciones muy desagradables que muchas veces desembocan en maltrato psicológico y físico.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Y aunque esto es harto conocido por la sociedad, es un modelo que se sigue usando con frecuencia.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Horario de trabajo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;En algunos casos las trabajadoras libran el fin de semana, 36 horas consecutivas según la ley, lo que podría ser de sábado a las 9:00 hasta el domingo a las 21:00, además de 2 horas al día (no remuneradas) en los días de entre semana. Esto hace un total de 122 horas trabajadas a la semana, mucho mayor de las 40 horas establecidas.&lt;/p&gt; &lt;p&gt;Y aunque en teoría &lt;a href=&#34;https://www.elsaltodiario.com/trabajo-domestico/justicia-europea-tira-orejas-espana-obliga-registrar-jornada-trabajadoras-del-hogar&#34;&gt;los empleadores están obligados a implementar un sistema para registrar la jornada de sus trabajadoras&lt;/a&gt; se torna &lt;a href=&#34;https://www.elsaltodiario.com/trabajo-domestico/registrar-jornada-laboral-empleo-hogar&#34;&gt;difícil en la práctica&lt;/a&gt;&lt;/p&gt; &lt;p&gt;La ley además establece que además de las 40 horas semanales se pueden tener 20 horas extras de presencia. Las horas de presencia se pagan a precio de hora normal porque el régimen de empleadas de hogar lo establece así. No es como otros convenios.&lt;/p&gt; &lt;p&gt;La mayor parte de las trabajadoras no conoce que tienen derecho a estas 20 horas adicionales. Esas horas de presencia se pueden reclamar por los últimos 12 meses, las anteriores prescriben. Esto pueden ser unos 18.000 euros a reclamar. Para ello hacen falta pruebas de que la trabajadora está haciendo esa jornada. Una manera de pelearlo es pedir al empleador que justifique qué otras personas tiene contratadas para cuidar a la persona dependiente. Porque la prueba dentro de un domicilio es muy difícil. Si en el contrato no figura ningún horario se puede asumir que es 24h. También se puede preguntar a vecinos o si está empadronada.&lt;/p&gt; &lt;p&gt;Lo que si es claro es que la empresa tiene que definir el horario de trabajo en el contrato, lo que no siempre hacen.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Pernocta&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;En el contrato tiene que figurar si la trabajadora duerme en el lugar de trabajo.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.elsaltodiario.com/trabajo-domestico/registrar-jornada-laboral-empleo-hogar&#34;&gt;Es muy difícil de regular las veces que se despiertan en la noche, así que pelear eso es aún complicado.&lt;/a&gt; Aunque se van haciendo avances.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Violencia y acoso en el empleo doméstico&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Según el &lt;a href=&#34;https://www.boe.es/buscar/act.php?id=BOE-A-2024-18182&#34;&gt;Real Decreto 893/2024&lt;/a&gt; a ojos de &lt;a href=&#34;https://noticias.juridicas.com/actualidad/noticias/19543-real-decreto-893-2024:-nuevos-derechos-laborales-para-las-empleadas-de-hogar-y-de-ayuda-a-domicilio-/&#34;&gt;noticias.juridicas.com&lt;/a&gt;:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;El abandono del domicilio ante una situación de violencia o acoso sufrida por la persona trabajadora no podrá considerarse dimisión ni podrá ser causa de despido, sin perjuicio de la posibilidad de la persona trabajadora de solicitar la extinción del contrato en virtud del artículo 50 ET y de la solicitud de medidas cautelares en caso de formulación de demandas, de conformidad con la LRJS.&lt;/p&gt; &lt;/blockquote&gt; &lt;p&gt;&lt;strong&gt;Salario&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Lo normal es que se pague el salario mínimo, aunque &lt;a href=&#34;https://www.elsaltodiario.com/trabajo-domestico/empleadas-hogar-internas-trabajan-maximo-60-horas-semanales&#34;&gt;Cuatro de cada diez ni llegan a eso&lt;/a&gt;. Hay que tener en cuenta que el salario mínimo ha sido actualizado desde enero de 2025 a 1383 euros. Es probable que a muchas ni se lo suban.&lt;/p&gt; &lt;p&gt;Si se cuentan las 20 horas de presencia, el salario serían aproximadamente 2000 euros al mes (2094 según la &lt;a href=&#34;https://www.sendadecuidados.org/cuidados-en-el-hogar/tablas-salariales/&#34;&gt;tabla salarial de senda de cuidados de 2024&lt;/a&gt; para un régimen de 6 noches a la semana).&lt;/p&gt; &lt;p&gt;&lt;em&gt;Pelear por sus derechos*&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Normalmente aunque les cuentes todos los derechos que tienen, las trabajadoras no quieren reclamar ni ejercer sus derechos porque no se atreven. Por miedo a perder el trabajo u otras represalias.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Datos personales&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Las asesorías pueden sacar el número de la seguridad social con un nombre y un DNI. Esto se hace para facilitar los trámites. Pero si no lo sabes puede rayarte.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Forma de pago&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;El empleador es el encargado de hacer la transferencia al trabajador como una nómina, no como una transferencia regular. Ya que si no el trabajador no obtiene las bonificaciones de tener domiciliada la nómina.&lt;/p&gt; &lt;p&gt;Aunque haya agencias de por medio, estas generalmente hacen de intermediarias y sólo un trabajo de asesoría, por lo tanto el contrato se suele hacer con la familia de la persona que es cuidada, y esta es la que ha de hacer el ingreso a la trabajadora. A no ser que la agencia sea una ETT de empleadas del hogar, que en ese caso es la agencia la que las contrata directamente.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Denuncias de inspección de trabajo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Las denuncias de inspección de trabajo en este régimen tienen un recorrido diferente dependiendo de a qué inspector le toque, porque como inspección de trabajo no puede entrar en los domicilios particulares por sorpresa aunque sea una empresa. Entonces hay inspectores que las denuncias por maltrato de las empleadas del hogar las meten en el cajón. Otros no, requieren y de más.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Impuestos&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;En las nóminas de las empleadas del hogar no hay IRPF. Normalmente el salario y la prorrata se desglosa, si está junto es una nómina cutre.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Papeleos&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Una vez firmado el contrato, la empresa ha de entregar a la trabajadora la huella digital de su contrato comunicado al servicio público de empleo. Cuando haces un alta de una trabajadora hay que mandar dos ficheros, uno a la tesorería general con el alta y otro al servicio público de empleo estatal con el contrato. Si no lo hacen es un defecto formal, no es gravísimo.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Referencias&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Empresas decentes: No todo es horrendo, existen cooperativas de trabajadoras que ofrecen estos servicios bajo unas condiciones que ellas han decidido:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.sendadecuidados.org/&#34;&gt;Senda de cuidados&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.lacomala.org/&#34;&gt;La Comala&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Senda de cuidados publica su &lt;a href=&#34;https://www.sendadecuidados.org/cuidados-en-el-hogar/tablas-salariales/&#34;&gt;tabla salarial&lt;/a&gt; en la que te puedes hacer una idea del salario y de los diferentes tipos de régimen de trabajo.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Mejoras legales&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.boe.es/buscar/act.php?id=BOE-A-2024-18182&#34;&gt;Real Decreto 893/2024, de 10 de septiembre, por el que se regula la protección de la seguridad y la salud en el ámbito del servicio del hogar familiar.&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.boe.es/diario_boe/txt.php?id=BOE-A-2022-14680&#34;&gt;Real Decreto-ley 16/2022, de 6 de septiembre, para la mejora de las condiciones de trabajo y de Seguridad Social de las personas trabajadoras al servicio del hogar.&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Artículos sobre el trabajo interno&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.elsaltodiario.com/trabajo-domestico/empleadas-hogar-internas-trabajan-maximo-60-horas-semanales&#34;&gt; Trabajo doméstico Dos de cada tres empleadas del hogar internas trabajan más del máximo de 60 horas semanales &lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.elsaltodiario.com/trabajo-domestico/justicia-europea-tira-orejas-espana-obliga-registrar-jornada-trabajadoras-del-hogar&#34;&gt;La justicia europea tira de las orejas a España y obliga a registrar la jornada de las trabajadoras del hogar&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.elsaltodiario.com/trabajo-domestico/registrar-jornada-laboral-empleo-hogar&#34;&gt;Registrar la jornada laboral en el empleo de hogar&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;collaborating-tools&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/collaborating_tools/&#34;&gt;Collaborating tools&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/collaborating_tools/#collaborating-event-date-picker&#34;&gt;Collaborating event date picker.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://crab.fit/&#34;&gt;https://crab.fit/&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/collaborating_tools/#collaborating-book-libraries&#34;&gt;Collaborating book libraries.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://inventaire.io/welcome&#34;&gt;https://inventaire.io/welcome&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;aleph&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/&#34;&gt;Aleph&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Correct the releases url.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/alephdata/aleph/releases/&#34;&gt;latest release&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add warning for new potential users.&lt;/p&gt; &lt;p&gt;WARNING: Check out the &lt;a href=&#34;https://lyz-code.github.io/blue-book/investigative_journalism/&#34;&gt;investigative journalism article before using Aleph&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Compare investigative journalism tools.&lt;/p&gt; &lt;p&gt;After reviewing Aleph Pro, Open Aleph, &lt;a href=&#34;https://dataresearchcenter.org/&#34;&gt;DARC&lt;/a&gt; and Datashare I feel that the investigative reporting software environment, as of June 2025, is very brittle and under a huge crisis that will have a breaking point on October of 2025, day where OCCRP will do the switch from Aleph to Aleph Pro.&lt;/p&gt; &lt;p&gt;Given this scenario, I think the best thing to do, if you already have an Aleph instance, is to keep using it until things stabilise. As you won\&#39;t have software updates since October 2025, I suggest that from then on you protect the service behind an VPN and/or SSL client certificate.&lt;/p&gt; &lt;p&gt;I also feel it\&#39;s also a great moment to make a strategic decision on how you want to use an investigative reporting platform. Some key questions are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;How much do you care of our data being leaked or lost by third parties?&lt;/li&gt; &lt;li&gt;How much do you trust OCCRP, DARC or ICIJ?&lt;/li&gt; &lt;li&gt;Do you want to switch from a self hosted platform to an external managed one? Will they be able to give a better service?&lt;/li&gt; &lt;li&gt;If you want to stay on the self hosted solution. Shall you migrate to Datashare instead of Open Aleph?&lt;/li&gt; &lt;li&gt;How dependent are you on open source software? How fragile are the teams that support that software? Can you help change that fragility?&lt;/li&gt; &lt;li&gt;Shall you use the AI for your investigative processes? If so, where and when?&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;I hope the analysis below may help shed some light on some of these questions. The only one that is not addressed is the AI as it\&#39;s a more political, philosophical one, that would make the document even longer.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Analysis of the present&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Development dependent in US government&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The two main software are developed by non-profits, Aleph by OCCRP and Datashare by ICIJ, that received part of their funding from the US government. This funding was lost after Naranjitler\&#39;s administration funding cuts:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.occrp.org/en/feature/with-a-strike-of-a-pen-trumps-aid-cuts-threaten-independent-journalism-around-the-world&#34;&gt;OCCRP lost this year 38% of their operational funds&lt;/a&gt;: \&#34;As a result, we had to lay off 40 people --- one fifth of our staff --- and have temporarily reduced some of the salaries of others. But there is more. OCCRP has also been funding a number of organizations across Europe, in some of the most difficult countries. Eighty percent of those sub-grants that we provide to other newsrooms have been cut as well.\&#34;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.icij.org/news/2025/03/unable-to-stay-in-the-country-unable-to-return-home-reporters-face-grim-prospects-after-latest-trump-cuts/&#34;&gt;ICIJ lost this year 8.6% of their operational funds&lt;/a&gt; with no apparent effects on the software or the staff.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;OCCRP decided to close the source code of Aleph triggering the team split up&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;With &lt;a href=&#34;https://www.occrp.org/en/announcement/occrp-announces-a-new-chapter-for-its-investigative-data-platform-aleph-pro&#34;&gt;OCCRP decision to close the source of Aleph&lt;/a&gt; an &lt;a href=&#34;https://dataresearchcenter.org/who-we-are/&#34;&gt;important part of their team&lt;/a&gt; (the co-leader of the research and data team, the Chief Data Editor and a developer) decided to &lt;a href=&#34;https://openaleph.org/blog/2025/03/OpenAleph-commits-to-the-commons/3510138e-16b3-4b5d-a06c-41af0aa2d517/&#34;&gt;leave the project&lt;/a&gt; and fund &lt;a href=&#34;https://dataresearchcenter.org&#34;&gt;DARC&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Although they look to &lt;a href=&#34;https://openaleph.org/blog/2025/03/OpenAleph-commits-to-the-commons/3510138e-16b3-4b5d-a06c-41af0aa2d517/&#34;&gt;be in good terms&lt;/a&gt;. They\&#39;re collaborating, although it could be OCCRP trying to save their face on this dark turn.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;These software have very few developers and no community behind them&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/alephdata/aleph/graphs/contributors&#34;&gt;Aleph&lt;/a&gt; looks to be currently developed by 2 developers, and it\&#39;s development has stagnated since the main developer (`pudo`) stopped developing and moved to &lt;a href=&#34;https://github.com/opensanctions/opensanctions/graphs/contributors&#34;&gt;Open Sanctions&lt;/a&gt; 4 years ago. 3 key members of their team have moved on to Open Aleph after the split. We can only guess if this is the same team that is developing Aleph Pro. If it\&#39;s not then they are developers we know nothing about and can\&#39;t audit.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/alephdata/aleph/compare/main...openaleph:openaleph:main&#34;&gt;Open Aleph&lt;/a&gt; looks to be developed by 4 people, 3 of them were part of the Aleph development team until the break up. The other one created a company to host Aleph instances 4 years ago.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/ICIJ/datashare/graphs/contributors&#34;&gt;Datashare&lt;/a&gt; seems to be developed by &lt;a href=&#34;https://www.icij.org/about/our-team/&#34;&gt;6 developers&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;In all projects pull requests by the community have been very scarce.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;The community support is not that great&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;My experience requesting features, proposing fixes with Aleph before the split is that they answer well on their slack, but are slow on the issues and the pull requests that fall outside their planned roadmap. Even if they are bugs. I\&#39;ve been running a script on each ingest to fix an UI bug for a year already. I tried to work with them in solving it without success.&lt;/p&gt; &lt;p&gt;I don\&#39;t have experience with Datashare, but they do answer and fix the issues the people open.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Analysis of the available software&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Aleph Pro&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The analysis is based on their &lt;a href=&#34;https://www.occrp.org/en/announcement/occrp-announces-a-new-chapter-for-its-investigative-data-platform-aleph-pro&#34;&gt;announcement&lt;/a&gt; and their &lt;a href=&#34;https://www.occrp.org/en/announcement/aleph-pro-frequently-asked-questions-on-the-future-of-occrps-investigative-data-platform&#34;&gt;FAQ&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;As long as you have less than 1TB of data and are a nonprofit it will, for now, cost you way less than hosting your solution&lt;/li&gt; &lt;li&gt;OCCRP is behind the project&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;They seem to have an unstable, small and broken development team&lt;/li&gt; &lt;li&gt; &lt;p&gt;They only offer 1TB of data which is enough for small to medium projects but doesn\&#39;t give much space to grow&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;They lost my trust&lt;/p&gt; &lt;p&gt;There are several reasons that make me hesitant to trust them:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;They don\&#39;t want to publish their source code&lt;/li&gt; &lt;li&gt;They decided that the path to solve a complicated financial situation is to close their source code&lt;/li&gt; &lt;li&gt;They advocated in the past (and even now!) that being open-sourced was a corner part of the project and yet they close their code.&lt;/li&gt; &lt;li&gt;They hid that &lt;a href=&#34;https://report.az/en/analytics/independent-investigation-us-gov-t-funded-occrp-and-appointed-its-leadership/&#34;&gt;52% of their funding came from the US government&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;With the next consequences:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;I would personally not give them my data or host their software.&lt;/li&gt; &lt;li&gt;I wouldn\&#39;t be surprised if in the future they retract on their promises, such as offering Aleph Pro for free forever for nonprofit journalism organizations.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;You loose sovereignty of your data&lt;/p&gt; &lt;p&gt;Either if you upload your data to their servers or host a closed sourced program in yours, you have no way of knowing what are they doing with your data. Given their economical situation, doing business with the data could be an option.&lt;/p&gt; &lt;p&gt;It could also be potentially difficult to extract your data in the future.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;You loose sovereignty of your service&lt;/p&gt; &lt;p&gt;If they host the service you depend on them for any operations such as maintenance, upgrades, and keeping the service up.&lt;/p&gt; &lt;p&gt;You\&#39;ll also no longer be able to change the software to apply patches to problems and would depend on them for their implementation and application.&lt;/p&gt; &lt;p&gt;You\&#39;ll no longer have any easy way to know what does the program do. This is critical from a security point of view as introduced backdoors would go unnoticed. It\&#39;s also worrying as we could not audit how they implement the AI. It is known that AI solutions tend to be biased and may thwart the investigative process.&lt;/p&gt; &lt;p&gt;Finally, if they decide to shutdown or change the conditions you\&#39;re sold.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;I looks like they are selling smoke&lt;/p&gt; &lt;p&gt;Their development activity has dropped in the recent years, they have a weakened team and yet they are promising a complete rewrite to create a brand new software. In an announce that is filled with buzzwords such as AI without giving any solid evidence.&lt;/p&gt; &lt;p&gt;I feel that the whole announcement is written to urge people to buy their product and to save their face. Its not written to the community or their users, is for those that can give them money.&lt;/p&gt; &lt;ol&gt; &lt;li&gt; &lt;p&gt;They offer significant performance upgrades and lower infrastructure costs at the same time that they incorporate the latest developments in data-analysis and AI&lt;/p&gt; &lt;p&gt;Depending on how they materialise the data-analysis and AI new features it will mean a small to a great increase in infrastructure costs. Hosting these processes is very resource intensive and expensive.&lt;/p&gt; &lt;p&gt;The decrease in infra costs may come from:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Hosting many aleph instances under the same infrastructure is more efficient than each organisation having their own.&lt;/li&gt; &lt;li&gt;They might migrate the code to a more efficient language like rust or go&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;So even though Aleph Pro will require more resources, as they are all going to be hosted in OCCRP it will be cheaper overall.&lt;/p&gt; &lt;p&gt;I\&#39;m not sure how they want to implement the AI, I see two potential places:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;To improve the ingest process.&lt;/li&gt; &lt;li&gt;To use LLM (like ChatGPT) to query the data.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Both features are very, very, very expensive resource wise. The only way to give those features at the same time as lowering the infra costs is by outsourcing the AI services. If they do this, it will mean that your data will be processed by that third party, with all the awful consequences it entails.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;They are selling existent features as new or are part of other open source projects&lt;/p&gt; &lt;p&gt;Such as:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Rebuilt the ingest pipeline: they recently released it in the latest versions of Aleph&lt;/li&gt; &lt;li&gt;Modular design: The source is already modular (although it can always be improved)&lt;/li&gt; &lt;li&gt;Enhanced data models for better linking, filtering, and insights. Their model is based on followthemoney which is open source.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ol&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;They are ditching part of their user base&lt;/p&gt; &lt;p&gt;They only support self-hosted solutions to enterprise license clients. This leaves out small organisations or privacy minded individuals. Even this solution is said to be maintained in partnership with OCCRP.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;The new version benefits may not be worth the costs&lt;/p&gt; &lt;p&gt;They say that Aleph Pro will deliver a faster, smarter, and more flexible platform, combining a modern technical foundation with user-centered design and major performance gains. But if you do not do a heavy use of the service you may not need some of these improvements. Although they for sure would be nice to have.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;It could be unstable for a while&lt;/p&gt; &lt;p&gt;A complete platform rewrite is usually good in the long run but these kind of migrations tend to have an unstable period of time where some of the functionality might be missing&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;You need to make the decision blindly&lt;/p&gt; &lt;p&gt;Even though they are going to give a beta if you request it, I\&#39;m not sure of this, before doing the switch, you need to make the decision beforehand. You may not even like the new software&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Datashare&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;ICIJ, a more reliable non profit, is behind it.&lt;/li&gt; &lt;li&gt;Has the biggest and stable development team&lt;/li&gt; &lt;li&gt;Is the most active project&lt;/li&gt; &lt;li&gt;Better community support&lt;/li&gt; &lt;li&gt;You can host it&lt;/li&gt; &lt;li&gt;It\&#39;s open source&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;If you have an Aleph instance there is no documented way to migrate to Datashare. And there is still not an easy way to do the migration, as they don&#39;t yet use the &lt;code&gt;followthemoney&lt;/code&gt; data schema.&lt;/li&gt; &lt;li&gt;They won\&#39;t host an instance for you.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Open Aleph&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;You can host it&lt;/li&gt; &lt;li&gt;It\&#39;s open source&lt;/li&gt; &lt;li&gt;The hosted solution will probably cost you way less than hosting your own solution (although &lt;a href=&#34;https://openaleph.org/managed/&#34;&gt;they don\&#39;t show prices&lt;/a&gt;)&lt;/li&gt; &lt;li&gt;The people behind it have proven their ethic values&lt;/li&gt; &lt;li&gt;I know one of their developers. She is a fantastic person which is very involved in putting technology in the service of society, and has been active at the CCC.&lt;/li&gt; &lt;li&gt;They are actively reaching out to give support with the migration&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;A new small organisation is behind the project&lt;/li&gt; &lt;li&gt;A small development team with few recent activity. Since their creation (3 months ago) their development &lt;a href=&#34;https://github.com/openaleph/openaleph/pulse/monthly&#34;&gt;pace is slow&lt;/a&gt; (the contributors don\&#39;t even load). It could be because they are still setting up the new organisation and doing the fork.&lt;/li&gt; &lt;li&gt;It may not have all the features Aleph has. They started the fork on November of 2024 and are 137 commits ahead and 510 behind. But they could be squash commits.&lt;/li&gt; &lt;li&gt;Their &lt;a href=&#34;https://darc.social/&#34;&gt;community forum&lt;/a&gt; doesn\&#39;t have much activity&lt;/li&gt; &lt;li&gt;The remote hosted solution has the same problems as Aleph Pro in terms of data and service sovereignty. Although I do trust more DARC than OCCRP.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;conference-organisation&#34;&gt;Conference organisation&lt;/h3&gt; &lt;h4 id=&#34;pretalx&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/pretalx/&#34;&gt;pretalx&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/pretalx/#import-a-pretalx-calendar-in-giggity&#34;&gt;Import a pretalx calendar in giggity.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Search the url similar to &lt;a href=&#34;https://pretalx.com/&#34;&gt;https://pretalx.com/&lt;/a&gt;&lt;conference-name&gt;/schedule/export/schedule.xml&lt;/conference-name&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/pretalx/#references&#34;&gt;Add references for pretalx.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://pretalx.com/p/about/&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/pretalx/pretalx&#34;&gt;Source&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/pretalx/#install&#34;&gt;Install.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;NOTE: it&#39;s probably too much for a small event.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/pretalx/pretalx-docker&#34;&gt;Docker compose&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/pretalx/pretalx-docker/issues/75&#34;&gt;The default docker compose doesn&#39;t work&lt;/a&gt; as it still uses &lt;a href=&#34;https://pretalx.com/p/news/releasing-pretalx-2024-3-0/&#34;&gt;mysql which was dropped&lt;/a&gt;. If you want to use sqlite just remove the database configuration.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;pretalx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;pretalx/standalone:v2024.3.0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;container_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;pretalx&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;restart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;unless-stopped&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;depends_on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;redis&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;environment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Hint: Make sure you serve all requests for the `/static/` and `/media/` paths when debug is False. See [installation](https://docs.pretalx.org/administrator/installation/#step-7-ssl) for more information&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;PRETALX_FILESYSTEM_MEDIA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/public/media&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;PRETALX_FILESYSTEM_STATIC&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/public/static&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ports&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;127.0.0.1:80:80&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;./conf/pretalx.cfg:/etc/pretalx/pretalx.cfg:ro&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;pretalx-data:/data&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;pretalx-public:/public&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;redis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;redis:latest&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;container_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;pretalx-redis&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;restart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;unless-stopped&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;pretalx-redis:/data&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;pretalx-data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;pretalx-public&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;pretalx-redis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;I was not able to find the default admin user so I had to create it manually. Get into the docker:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-it&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pretalx&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;bash
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;When you run the commands by default it uses another database file &lt;code&gt;/pretalx/src/data/db.sqlite3&lt;/code&gt;, so I removed it and created a symbolic link to the actual place of the database &lt;code&gt;/data/db.sqlite&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pretalxuser@82f886a58c57:/$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/pretalx/src/data/db.sqlite3
pretalxuser@82f886a58c57:/$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ln&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/data/db.sqlite3&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/pretalx/src/data/db.sqlite3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then you can create the admin user:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;python&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-m&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pretalx&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;createsuperuser
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;life-navigation&#34;&gt;Life navigation&lt;/h2&gt; &lt;h3 id=&#34;time-navigation&#34;&gt;Time navigation&lt;/h3&gt; &lt;h4 id=&#34;org-mode&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/&#34;&gt;Org Mode&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#footnotes&#34;&gt;Footnotes.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;A footnote is started by a footnote marker in square brackets in column 0, no indentation allowed. It ends at the next footnote definition, headline, or after two consecutive empty lines. The footnote reference is simply the marker in square brackets, inside text. Markers always start with ‘fn:’. For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;The Org website[fn:1] now looks a lot better than it used to.
...
[fn:50] The link is: https://orgmode.org
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Nvim-orgmode has &lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/commit/4f62b7f#diff-fa091537281e07e5e58902b6484b097442300c98e115ab29f4374abbe98b8d3d&#34;&gt;some basic support for footnotes&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#custom-agendas&#34;&gt;Custom agendas.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You an use &lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/blob/d62fd3cdb2958e2e76fb0af4ea64d6209703fbe0/DOCS.md#org_agenda_custom_commands&#34;&gt;custom agenda commands&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Define custom agenda views that are available through the &lt;code&gt;org_agenda&lt;/code&gt; mapping. It is possible to combine multiple agenda types into single view. An example: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;orgmode&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;org_agenda_files&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;~/org/**/*&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;org_agenda_custom_commands&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;-- &#34;c&#34; is the shortcut that will be used in the prompt&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;c&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;description&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;Combined view&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- Description shown in the prompt for the shortcut&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;types&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;tags_todo&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- Type can be agenda | tags | tags_todo&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;match&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;+PRIORITY=&#34;A&#34;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;--Same as providing a &#34;Match:&#34; for tags view &amp;lt;leader&amp;gt;oa + m, See: https://orgmode.org/manual/Matching-tags-and-properties.html&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_overriding_header&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;High priority todos&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_todo_ignore_deadlines&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;far&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- Ignore all deadlines that are too far in future (over org_deadline_warning_days). Possible values: all | near | far | past | future&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;agenda&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_overriding_header&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;My daily agenda&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_span&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;day&#39;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- can be any value as org_agenda_span&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;tags&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;match&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;WORK&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;--Same as providing a &#34;Match:&#34; for tags view &amp;lt;leader&amp;gt;oa + m, See: https://orgmode.org/manual/Matching-tags-and-properties.html&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_overriding_header&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;My work todos&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_todo_ignore_scheduled&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;all&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- Ignore all headlines that are scheduled. Possible values: past | future | all&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;agenda&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_overriding_header&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;Whole week overview&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_span&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;week&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- &#39;week&#39; is default, so it&#39;s not necessary here, just an example&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_start_on_weekday&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- Start on Monday&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_remove_tags&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- Do not show tags only for this view&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
     &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;description&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;Personal agenda&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;types&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;tags_todo&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_overriding_header&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;My personal todos&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_category_filter_preset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;todos&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- Show only headlines from `todos` category. Same value providad as when pressing `/` in the Agenda view&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_sorting_strategy&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;todo-state-up&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;priority-down&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- See all options available on org_agenda_sorting_strategy&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;agenda&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_overriding_header&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;Personal projects agenda&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_files&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;~/my-projects/**/*&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- Can define files outside of the default org_agenda_files&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;tags&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_overriding_header&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;Personal projects notes&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_files&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;~/my-projects/**/*&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_tag_filter_preset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;NOTES-REFACTOR&#39;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- Show only headlines with NOTES tag that does not have a REFACTOR tag. Same value providad as when pressing `/` in the Agenda view&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;You can also define the &lt;code&gt;org_agenda_sorting_strategy&lt;/code&gt;. The default value is &lt;code&gt;{ agenda = {&#39;time-up&#39;, &#39;priority-down&#39;, &#39;category-keep&#39;}, todo = {&#39;priority-down&#39;, &#39;category-keep&#39;}, tags = {&#39;priority-down&#39;, &#39;category-keep&#39;}}&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;The available list of sorting strategies to apply to a given view are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;time-up&lt;/code&gt;: Sort entries by time of day. Applicable only in agenda view&lt;/li&gt; &lt;li&gt;&lt;code&gt;time-down&lt;/code&gt;: Opposite of time-up&lt;/li&gt; &lt;li&gt;&lt;code&gt;priority-down&lt;/code&gt;: Sort by priority, from highest to lowest&lt;/li&gt; &lt;li&gt;&lt;code&gt;priority-up&lt;/code&gt;: Sort by priority, from lowest to highest&lt;/li&gt; &lt;li&gt;&lt;code&gt;tag-up&lt;/code&gt;: Sort by sorted tags string, ascending&lt;/li&gt; &lt;li&gt;&lt;code&gt;tag-down&lt;/code&gt;: Sort by sorted tags string, descending&lt;/li&gt; &lt;li&gt;&lt;code&gt;todo-state-up&lt;/code&gt;: Sort by todo keyword by position (example: &#39;TODO, PROGRESS, DONE&#39; has a sort value of 1, 2 and 3), ascending&lt;/li&gt; &lt;li&gt;&lt;code&gt;todo-state-down&lt;/code&gt;: Sort by todo keyword, descending&lt;/li&gt; &lt;li&gt;&lt;code&gt;clocked-up&lt;/code&gt;: Show clocked in headlines first&lt;/li&gt; &lt;li&gt;&lt;code&gt;clocked-down&lt;/code&gt;: Show clocked in headines last&lt;/li&gt; &lt;li&gt;&lt;code&gt;category-up&lt;/code&gt;: Sort by category name, ascending&lt;/li&gt; &lt;li&gt;&lt;code&gt;category-down&lt;/code&gt;: Sort by category name, descending&lt;/li&gt; &lt;li&gt;&lt;code&gt;category-keep&lt;/code&gt;: Keep default category sorting, as it appears in org-agenda-files&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;You can open the custom agendas with the API too. For example to open the agenda stored under &lt;code&gt;t&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;     &lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;gt&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
         &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;notify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Opening today&#39;s agenda&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;levels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INFO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
          &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;orgmode.api.agenda&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open_by_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;t&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Open orgmode agenda for today&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;In that case I&#39;m configuring the &lt;code&gt;keys&lt;/code&gt; section of the lazyvim plugin. Through the API you can also configure these options:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;org_agenda_files&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;org_agenda_sorting_strategy&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;org_agenda_category_filter_preset&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;org_agenda_todo_ignore_deadlines&lt;/code&gt;: Ignore all deadlines that are too far in future (over org_deadline_warning_days). Possible values: all | near | far | past | future&lt;/li&gt; &lt;li&gt;&lt;code&gt;org_agenda_todo_ignore_scheduled&lt;/code&gt;: Ignore all headlines that are scheduled. Possible values: past | future | all&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#load-different-agendas-with-the-same-binding-depending-on-the-time&#34;&gt;Load different agendas with the same binding depending on the time.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I find it useful to bind &lt;code&gt;gt&lt;/code&gt; to Today&#39;s agenda, but what today means is different between week days. Imagine that you want to load an agenda if you&#39;re from monday to friday before 18:00 (a work agenda) versus a personal agenda the rest of the time.&lt;/p&gt; &lt;p&gt;You could then configure this function:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;    &lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
     &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;gt&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
          &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;current_time&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;os.date&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;*t&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
          &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;day&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;current_time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wday&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- 1 = Sunday, 2 = Monday, etc.&lt;/span&gt;
          &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hour&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;current_time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hour&lt;/span&gt;

          &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;agenda_key&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;t&#34;&lt;/span&gt;
          &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;agenda_name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Today&#39;s&#34;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- default&lt;/span&gt;

          &lt;span class=&#34;c1&#34;&gt;-- Monday (2) through Friday (6)&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;day&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;day&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
            &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hour&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;17&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
              &lt;span class=&#34;n&#34;&gt;agenda_key&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;w&#34;&lt;/span&gt;
              &lt;span class=&#34;n&#34;&gt;agenda_name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Today + Work&#34;&lt;/span&gt;
            &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;

          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;notify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Opening &#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;agenda_name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34; agenda&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;levels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INFO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
          &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;orgmode.api.agenda&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open_by_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;agenda_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Open orgmode agenda for today&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#better-handle-indentations&#34;&gt;Better handle indentations.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;There is something called &lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/blob/master/docs/configuration.org#org_startup_indented&#34;&gt;virtual indents&lt;/a&gt; that will prevent you from many indentation headaches. To enable them set the &lt;code&gt;org_startup_indented = true&lt;/code&gt; configuration.&lt;/p&gt; &lt;p&gt;If you need to adjust the indentation of your document (for example after enabling the option on existent orgmode code), visually select the lines to correct the indentation (&lt;code&gt;V&lt;/code&gt;) and then press &lt;code&gt;=&lt;/code&gt;. You can do this with the whole file &lt;code&gt;(╥﹏╥)&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#remove-some-tags-when-the-state-has-changed-so-done&#34;&gt;Remove some tags when the state has changed so DONE.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;For example if you want to remove them for recurrent tasks&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;      &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;remove_specific_tags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tagsToRemove&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;t&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;w&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;m&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;q&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;y&#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
        &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;currentTags&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;headline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_tags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;newTags&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
        &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;needsUpdate&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;

        &lt;span class=&#34;c1&#34;&gt;-- Build new tags list excluding t, w, m&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tag&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;ipairs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;currentTags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;do&lt;/span&gt;
          &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;shouldKeep&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;removeTag&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;ipairs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tagsToRemove&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;do&lt;/span&gt;
            &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tag&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;removeTag&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
              &lt;span class=&#34;n&#34;&gt;shouldKeep&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;
              &lt;span class=&#34;n&#34;&gt;needsUpdate&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
              &lt;span class=&#34;kr&#34;&gt;break&lt;/span&gt;
            &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;shouldKeep&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
            &lt;span class=&#34;nb&#34;&gt;table.insert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newTags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;-- Only update if we actually removed something&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;needsUpdate&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;headline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set_tags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;table.concat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newTags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;:&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;headline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;refresh&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
      &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;

      &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;EventManager&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;orgmode.events&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;EventManager&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;listen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EventManager&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TodoChanged&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;---@cast event OrgTodoChangedEvent&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headline&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;DONE&#34;&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;remove_specific_tags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
      &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#register-the-todo-changes-in-the-logbook&#34;&gt;Register the todo changes in the logbook.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can now register the changes with events. Add this to your plugin config. If you&#39;re using lazyvim:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;nvim-orgmode/orgmode&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
      &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;orgmode&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({...})&lt;/span&gt;

      &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;EventManager&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;orgmode.events&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
      &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Date&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;orgmode.objects.date&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

      &lt;span class=&#34;n&#34;&gt;EventManager&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;listen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EventManager&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TodoChanged&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;---@cast event OrgTodoChangedEvent&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headline&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
         &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;current_todo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_todo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
          &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;now&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Date&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

          &lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_note&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
            &lt;span class=&#34;s1&#34;&gt;&#39;State &#34;&#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;current_todo&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&#34; from &#34;&#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;old_todo_state&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&#34;  [&#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;to_string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;]&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
      &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#api-usage&#34;&gt;API usage.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/commit/2c806ca&#34;&gt;Get the headline under the cursor&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/commit/500004ff315475033e3a9247b61addd922d1f5da&#34;&gt;Read and write files&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You have information on how to do it in &lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/commit/500004ff315475033e3a9247b61addd922d1f5da&#34;&gt;this pr&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/commit/8cdfc8d34bd9c5993ea8f933b5f5c306081ffb97&#34;&gt;Create custom hyperlink types&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Custom types can trigger functionality such as opening the terminal and pings the provided URL .&lt;/p&gt; &lt;p&gt;To add your own custom hyperlink type, provide a custom handler to &lt;code&gt;hyperlinks.sources&lt;/code&gt; setting. Each handler needs to have a &lt;code&gt;get_name()&lt;/code&gt; method that returns a name for the handler. Additionally, &lt;code&gt;follow(link)&lt;/code&gt; and &lt;code&gt;autocomplete(link)&lt;/code&gt; optional methods are available to open the link and provide the autocompletion. ## &lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/issues/471#event-16071077147&#34;&gt;Refile a headline to another destination&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/issues/471#event-16071077147&#34;&gt;Refile a headline to another destination&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can do this &lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/blob/master/doc/orgmode_api.txt#L27&#34;&gt;with the API&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Assuming you are in the filewhere your TODOs are:&lt;/p&gt; &lt;p&gt;local api = require(&#39;orgmode.api&#39;) local closest_headline = api.current():get_closest_headline() local destination_file = api.load(&#39;~/org/journal.org&#39;) ocal destination_headline = vim.tbl_filter(function(headline) return headline.title == &#39;My journal&#39; end, destination_file.headlines)[1]&lt;/p&gt; &lt;p&gt;api.refile({ source = closest_headline, destination = destination_headline })&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/tree/master/lua/orgmode/events&#34;&gt;Use events&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce the time navigation abstract identity concept.&lt;/p&gt; &lt;p&gt;An &lt;a href=&#34;https://en.m.wikipedia.org/wiki/Identity_%28social_science%29&#34;&gt;identity&lt;/a&gt; is the set of qualities, beliefs, personality traits, appearance, and/or expressions that characterize a person or a group.&lt;/p&gt; &lt;p&gt;Identity serves multiple functions, acting as a &#34;self-regulatory structure&#34; that provides meaning, direction, and a sense of self-control. It fosters internal harmony and serves as a behavioral compass, enabling individuals to orient themselves towards the future and establish long-term goals. As an active process, it profoundly influences an individual&#39;s capacity to adapt to life events and achieve a state of well-being. However, identity originates from traits or attributes that you may have little or no control over, such as their family background or ethnicity.&lt;/p&gt; &lt;p&gt;Identities then will be the guide of my life. I&#39;ve tried setting essential goals, answering big questions with no success so far. This approach however looks more interesting because:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;I can split myself in many identities each with it&#39;s definition and analyse life through the different lenses, identify identity conflicts, priorize identities...&lt;/li&gt; &lt;li&gt;I can analyse each identity on it&#39;s own, decide how to change my roadmap to integrate the ones I want to adopt and get away from the ones I want to leave behind.&lt;/li&gt; &lt;li&gt;It reminds me of the RPG character building and although it may seem silly, that motivates me.&lt;/li&gt; &lt;li&gt;It fits quite well with what I&#39;ve learnt regarding &lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/&#34;&gt;habit management&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;The identities archive&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;I&#39;m using a new notebook page called &lt;code&gt;identities.org&lt;/code&gt; where I plan to analyze, build and evolve my identities.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;An identity section&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Each identity may have the next sections. A simple heading with the name of the identity is just fine. You&#39;ll create the sections as long as you need them.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Analysis of the identity&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Here we can develop our thoughts on what does the identity mean and what do you see yourself embodying the identity&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Identity characteristics&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;List the values, habits, abilities, knowledge, capabilities and experiences that define the identity, and analyse each of them.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Identity plan&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Here is where we can sketch the plan we want to follow to grow or shrink this identity. It contains a list of &lt;a href=&#34;https://lyz-code.github.io/blue-book/axis/&#34;&gt;identity axis&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Children identities&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Sometimes an identity can be refined in smaller more specific identities, here we&#39;ll add sections for each of them.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Identity analysis&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Dump your thoughts on your identities&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Before we get tainted with our past analysis imagine a fresh canvas and start painting yourself.&lt;/p&gt; &lt;p&gt;You can add a section in &lt;code&gt;think.org&lt;/code&gt; to record your findings. I found that I needed some time to do this dump, working on the section through days before the actual analysis.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Do an initial list of values&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;I first created a &lt;code&gt;global values or principles&lt;/code&gt; headline and listed all core principles such as:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;All creatures are beautiful&lt;/li&gt; &lt;li&gt;Be excellent to each other&lt;/li&gt; &lt;li&gt;Better done than perfect&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;You may refactor them into the identities once you start building them.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Do an initial list of identities&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Empty your mind of the different identities that define you or that you want to be defined by. Create headlines for each using the sections defined above as you need them.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Do an initial list of axis&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Dream of what &lt;a href=&#34;https://lyz-code.github.io/blue-book/axis/&#34;&gt;axis&lt;/a&gt; you&#39;ll want to address. If you can order them into identities.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Do the identity analysis&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Refactor the gathered thoughts into the &lt;code&gt;identities.org&lt;/code&gt; file&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Select the identities you want to prioritise in the year&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Skim over all identities and for the ones you want to focus in the year:&lt;/li&gt; &lt;li&gt;add the &lt;code&gt;identity&lt;/code&gt; tag&lt;/li&gt; &lt;li&gt;assign a priority&lt;/li&gt; &lt;li&gt;do not add a TODO keyword, we&#39;ll reserve them for the identity axis.&lt;/li&gt; &lt;li&gt;Use the year custom agenda &lt;code&gt;identities&lt;/code&gt; section to adjust the priority of the different identities following the next guides:&lt;/li&gt; &lt;li&gt;Spread the identities over the different priorities so that each has more less the same number of elements.&lt;/li&gt; &lt;li&gt;Compare an identity with the ones that are above or below and decide if you promote or demote it&lt;/li&gt; &lt;li&gt;If you don&#39;t want one identity to bien the list add the &lt;code&gt;backlog&lt;/code&gt; tag if you don&#39;t want that identity and it&#39;s subidentities to appear. Add the &lt;code&gt;hide&lt;/code&gt; tag in case you want any of the subidentities&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Refine the identities&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Following the priority order of identities go one by one until you run out of time and:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Read the identity analysis and the different &lt;a href=&#34;https://lyz-code.github.io/blue-book/axis/&#34;&gt;axis&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;Order the different axis by the impact they can have in the identity&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/axis/&#34;&gt;Refine the projects of each axis&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Use unison to sync.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#exporting&#34;&gt;Exporting to pdf or markdown.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;To pdf&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you want to convert it with python you first need to install the dependencies: &lt;code&gt;sudo apt install texlive-xetex&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Then you can do&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pandoc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;input.org&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output.pdf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--pdf-engine&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;xelatex&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-V&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;geometry:margin&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;1in&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-V&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fontsize&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;11pt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-V&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;colorlinks&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;To markdown&lt;/strong&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pandoc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;input.org&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output.md
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;axis&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgzly/&#34;&gt;Axis&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgzly/#not-adding-a-todo-state-when-creating-a-new-element-by-default&#34;&gt;Not adding a todo state when creating a new element by default.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The default state &lt;code&gt;NOTE&lt;/code&gt; doesn&#39;t add any state.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce the axis time navigation concept.&lt;/p&gt; &lt;p&gt;An identity axis is an abstract guide for action with an indefinite scope or a timeframe longer than one year. It serves as a high-level directional tool to materialise changes in your &lt;a href=&#34;https://lyz-code.github.io/blue-book/identities/&#34;&gt;identities&lt;/a&gt;, helping to outline a general course without specifying exact destinations.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Limitations of an axis&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;It is not suitable as a final destination on a roadmap because it is too ambiguous.&lt;/li&gt; &lt;li&gt;Even minor progress could be considered sufficient, leading to a lack of clear endpoints.&lt;/li&gt; &lt;li&gt;One could continue indefinitely without a sense of completion, such as continuously striving for improvement.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Axis orgmode representation&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;An axis is a headline or TODO headline (depending whether it&#39;s active or not) that is part of the &lt;code&gt;plan&lt;/code&gt; section of an &lt;a href=&#34;https://lyz-code.github.io/blue-book/identities/&#34;&gt;identity&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;It can have none or many of the next sections:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Axis analysis section&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To gather the thoughts regarding the study of the axis&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Axis plan section&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To gather the axis projects that will materialise the direction of the axis.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Axis projects&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To prevent endless pursuit, an axis should be broken down into projects with defined scopes that indicate when to stop advancing in that direction.&lt;/p&gt; &lt;p&gt;Axis projects shall:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Have a scope shorter than 11 months so they can be managed in the life stage review.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Depending on whether the axis projects will be acted upon in the current quarter they will have two possible representations:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;If you don&#39;t plan to it will be a project section with the análisis, and steps&lt;/li&gt; &lt;li&gt;If you do, then it will be a link to the project section either in &lt;code&gt;projects.org&lt;/code&gt; or in &lt;code&gt;backlog.org&lt;/code&gt;. You can leave the analysis section below the link in &lt;code&gt;identities.org&lt;/code&gt; that way it won&#39;t use precious space in your &lt;code&gt;projects.org&lt;/code&gt; file.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;roadmap-adjustment&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/roadmap_adjustment/&#34;&gt;Roadmap Adjustment&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Small annotations throughout the document.&lt;/p&gt; &lt;p&gt;The idea of each adjustment is that it&#39;s not cumbersome, so I&#39;ve decided to set a fixed time for each one, I assume that I&#39;ll do my best on both processes and wherever I reach is just fine (remember, better done than perfect).&lt;/p&gt; &lt;p&gt;I believe on the power of constant small changes, so the next review will be built on top of the current one, and thus it will be done better and faster.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/roadmap_adjustment/#year-review&#34;&gt;Do the first sketch of the year review.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;As the year comes to an end it can be a good idea to review stuff that has a year cadence of change and that people are reviewing, for example:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;#how-the-world-has-changed&#34;&gt;How the world has changed&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Relevant content stuff&lt;/li&gt; &lt;li&gt;Life experiences&lt;/li&gt; &lt;li&gt;Your toolset&lt;/li&gt; &lt;li&gt;Your economical year review&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;I&#39;m not going to review the year roadmap or how I&#39;ve changed or my tactics or strategies right now as I feel it makes more sense to do it in the &lt;a href=&#34;#life-review&#34;&gt;life review&lt;/a&gt; just before spring comes. In fact, we&#39;ll be able to do a better life review once we have the output of the review of the year.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Year review timeline&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;As you can see the amount of stuff to review is not something that can be done in a day, my current plan is to prepare the review of the year throughout December and carry it out on the first two weeks of January.&lt;/p&gt; &lt;p&gt;So I&#39;ve scheduled an action each 1&lt;sup&gt;st&lt;/sup&gt; of December with deadline on the 31&lt;sup&gt;st&lt;/sup&gt; to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Create a new entry in &lt;code&gt;think.org&lt;/code&gt; with the next format: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;* Year review (YYYY)
** Review adjustments
** Sections
*** How the world has changed
*** ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Then I created another action from the 1&lt;sup&gt;st&lt;/sup&gt; of January to the 15&lt;sup&gt;th&lt;/sup&gt; to actually do the review.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Year review phases&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;How the world has changed&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You don&#39;t live alone in a bubble, your life is affected by what is going on around you, so if you can it&#39;s always good to analyse it so that you can adjust your roadmap accordingly.&lt;/p&gt; &lt;p&gt;Doing this on January makes a lot of sense because most newspapers and important people do a year review which synthesizes the most important year events and how it has changed throughout the year.&lt;/p&gt; &lt;p&gt;I&#39;m usually gathering the analysis on the &lt;a href=&#34;https://lyz-code.github.io/blue-book/year_reviews/&#34;&gt;Year reviews&lt;/a&gt; article.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;How did my economy change this year&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;I take the chance to do a last review of the year through the lenses of my accounting system (&lt;a href=&#34;https://lyz-code.github.io/blue-book/beancount/&#34;&gt;beancount&lt;/a&gt;). I&#39;ve made some fava dashboards that gather the most interesting information.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Review the relevant content I&#39;ve consumed&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;With the use of &lt;a href=&#34;https://lyz-code.github.io/blue-book/mediatracker/&#34;&gt;mediatracker&lt;/a&gt; and other life logging tools I take a look at what content I&#39;ve enjoyed the most. I want to share it also with all of you through these articles:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/books/&#34;&gt;Books&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;movies.md&#34;&gt;Movies&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;tv_shows.md&#34;&gt;TV shows&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/podcasts/&#34;&gt;Podcasts&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;streaming_channels.md&#34;&gt;Streaming channels&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;music.md&#34;&gt;Music&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;videogames.md&#34;&gt;Videogames&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;boardgames.md&#34;&gt;Boardgames&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/roadmap_adjustment/#life-review&#34;&gt;First sketch of the life review.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Life reviews are meant to give you an idea of:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;How much have you and your workflows evolved&lt;/li&gt; &lt;li&gt;What roadmap decisions were right, which ones were wrong&lt;/li&gt; &lt;li&gt;With the context you have now, you can think of how you could have avoided the bad decisions.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;If you have the year&#39;s planning you can analyze it against your task management tools and life logs and create a review document analyzing all.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Life review timeline&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;As you can see the amount of stuff to review is not something that can be done in a day, my current plan is to prepare the review from the 15&lt;sup&gt;th&lt;/sup&gt; of December till the 15&lt;sup&gt;th&lt;/sup&gt; of January and then carry it out until the 23&lt;sup&gt;rd&lt;/sup&gt; of February, to leave space to do the spring quarter and March month reviews.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Adjust the month review process.&lt;/p&gt; &lt;p&gt;To record the results of the review create the section in &lt;code&gt;pages/reviews.org&lt;/code&gt; with the following template:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;* winter
** january review
*** work
*** personal
**** month review
***** mental dump
****** What worries you right now?
****** What drained your energy or brought you down emotionally this last month?
****** What are the little things that burden you or slow you down?
****** What do you desire right now?
****** Where is your mind these days?
****** What did you enjoy most this last month?
****** What did help you most this last month?
****** What things would you want to finish throughout the month so you can carry them to the next?
****** What things do you feel you need to do?
****** What are you most proud of this month?
***** month checks
***** analyze
***** decide
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;I&#39;m assuming it&#39;s the january&#39;s review and that you have two kinds of reviews, one personal and one for work.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Dump your mind&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The first thing we want to do in the review is to dump all that&#39;s in our mind into our system to free up mental load.&lt;/p&gt; &lt;p&gt;Try not to, but if you think of decisions you want to make that address the elements you&#39;re discovering, write them down in the &lt;code&gt;Decide&lt;/code&gt; section of your review document.&lt;/p&gt; &lt;p&gt;There are different paths to discover actionable items:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Analyze what is in your mind: Take 10 minutes to answer to the questions of the template under the &#34;mental dump&#34; section (you don&#39;t need to answer them all). Notice that we do not need to review our life logging tools (diary, action manager, ...) to answer these questions. This means that we&#39;re doing an analysis of what is in our minds right now, not throughout the month. It&#39;s flawed but as we do this analysis often, it&#39;s probably fine. We add more importance to the latest events in our life anyway.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Clean your notebook&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Empty the elements you added to the &lt;code&gt;review box&lt;/code&gt;. I have them in my inbox with the tag &lt;code&gt;:review:&lt;/code&gt; (you have it in the month agenda view &lt;code&gt;gM&lt;/code&gt;)&lt;/li&gt; &lt;li&gt;Clean your life notebook by:&lt;/li&gt; &lt;li&gt;Iterate over the areas of &lt;code&gt;proyects.org&lt;/code&gt; only checking the first level of projects, don&#39;t go deeper and for each element:&lt;ul&gt; &lt;li&gt;Move the done elements either to &lt;code&gt;archive.org&lt;/code&gt; or &lt;code&gt;logbook.org&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;Move to &lt;code&gt;backlog.org&lt;/code&gt; the elements that don&#39;t make sense to be active anymore&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Check if you have any &lt;code&gt;DONE&lt;/code&gt; element in &lt;code&gt;calendar.org&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;Empty the &lt;code&gt;inbox.org&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Empty the &lt;code&gt;DONE&lt;/code&gt; elements of &lt;code&gt;talk.org&lt;/code&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;Clean the elements that don&#39;t make sense anymore from &lt;code&gt;think.org&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Process your &lt;code&gt;month checks&lt;/code&gt;. For each of them:&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;If you need, add action elements in the &lt;code&gt;mental dump&lt;/code&gt; section of the review.&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Think of whether you&#39;ve met the check.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Refresh your idea of how the month go&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Open your &lt;code&gt;bitácora.org&lt;/code&gt; agenda view to see what has been completed in the last month &lt;code&gt;match = &#39;CLOSED&amp;gt;&#34;&amp;lt;-30d&amp;gt;&#34;-work-steps-done&#39;,&lt;/code&gt; ordered by name &lt;code&gt;org_agenda_sorting_strategy = { &#34;category-keep&#34; },&lt;/code&gt; and change the priority of the elements according to the impact. Open your &lt;code&gt;recurrent.org&lt;/code&gt; agenda view to see what has been done the last month &lt;code&gt;match = &#39;LAST_REPEAT&amp;gt;&#34;&amp;lt;-30d&amp;gt;&#34;-work&#39;&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Check what has been left of your month objectives &lt;code&gt;+m&lt;/code&gt; and refile the elements that don&#39;t make sense anymore.&lt;/li&gt; &lt;li&gt;Check the reports of your weekly reviews of the month in the &lt;code&gt;reviews.org&lt;/code&gt; document.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Check your close compromises&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Check all your action management tools (in my case &lt;code&gt;orgmode&lt;/code&gt; and &lt;code&gt;ikhal&lt;/code&gt;) to identify: - Arranged compromises - trips&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/roadmap_adjustment/#life-roadmap-adjustment&#34;&gt;Life roadmap adjustment.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Create next stage&#39;s life notebook&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;After reading &#34;The Bulletproof Journal&#34;, I was drawn to the idea of changing notebooks each year, carrying over only the necessary things.&lt;/p&gt; &lt;p&gt;I find this to be a powerful concept since you start each stage with a clean canvas. This brings you closer to desire versus duty as it removes the commitments you made to yourself, freeing up significant mental load. From this point, it&#39;s much easier to allow yourself to dream about what you want to do in this new stage.&lt;/p&gt; &lt;p&gt;I want to apply this concept to my digital life notebook as I see the following advantages:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;It lightens my files making them easier to manage and faster to process with orgmode&lt;/li&gt; &lt;li&gt;It&#39;s a very easy way to clean up&lt;/li&gt; &lt;li&gt;It&#39;s an elegant way to preserve what you&#39;ve recorded without it becoming a hindrance&lt;/li&gt; &lt;li&gt;In each stage, you can start with a different notebook structure, meaning new axes, tools, and structures. This helps avoid falling into the rigidity of a constrained system or artifacts defined by inertia rather than conscious decision&lt;/li&gt; &lt;li&gt;It allows you to avoid maintaining files that follow an old scheme or having to migrate them to the new system&lt;/li&gt; &lt;li&gt;Additionally, you get rid of all those actions you&#39;ve been reluctant to delete in one fell swoop&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The notebook change can be done in two phases:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Notebook Construction&lt;/li&gt; &lt;li&gt;Stage Closure&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Notebook Construction&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;This phase spans from when you start making stage adjustments until you finally close the current stage. You can follow these steps:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Create a directory with the name of the new stage. In my case, it&#39;s the number of my predominant age during the stage&lt;/li&gt; &lt;li&gt;Create a directory for the current stage&#39;s notebook within &#34;notebooks&#34; in your references. Here we&#39;ll move everything that doesn&#39;t make sense to maintain. It&#39;s important that this directory isn&#39;t within your agenda files&lt;/li&gt; &lt;li&gt;Quickly review the improvements you&#39;ve noted that you want to implement in next year&#39;s notebook to keep them in mind. You can note the references in the &#34;Create new notebook&#34; action&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;As you review the stage, decide if it makes sense for the file you&#39;re viewing to exist as-is in the new notebook. Remember that the idea is to migrate minimal structure and data.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;If it makes sense:&lt;/li&gt; &lt;li&gt;Create a symbolic link in the new notebook. When closing the stage, we&#39;ll replace the link with the file&#39;s final state&lt;/li&gt; &lt;li&gt;If the file no longer makes sense, move it to &lt;code&gt;references/notebooks&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/roadmap_adjustment/#life-stage-roadmap-adjustment&#34;&gt;Life stage roadmap adjustment adjustments.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Review what you&#39;ve done the last year&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Read your &lt;code&gt;logbook.org&lt;/code&gt; (o &lt;code&gt;bitácora.org&lt;/code&gt;) adjusting the priorities of the áreas, projects and actions thinking of the impact the element has meant in your live.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Review what you&#39;ve learn the last year&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;It&#39;s always interesting to look back and see what you&#39;ve learned throughout the year. I have these sources of data:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;#digital-garden&#34;&gt;Digital garden&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you happen to have a &lt;a href=&#34;https://lyz-code.github.io/blue-book/digital_garden/&#34;&gt;digital garden&lt;/a&gt; you can look at your git history to know what has changed since the last year. That&#39;s cumbersome and ugly though, it&#39;s better to review &lt;a href=&#34;https://lyz-code.github.io/blue-book/newsletter/0_newsletter_index/&#34;&gt;your newsletters&lt;/a&gt;, although you may need to use something like &lt;a href=&#34;https://lyz-code.github.io/mkdocs-newsletter/&#34;&gt;&lt;code&gt;mkdocs-newsletter&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;While you skim through the newsletters you can add to the analysis report the highlights of what you&#39;ve learned.&lt;/p&gt; &lt;p&gt;You can also check &lt;a href=&#34;https://lyz-code.github.io/blue-book/git/#get-interesting-stats-of-the-repo&#34;&gt;your repository insights&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;#anki&#34;&gt;Anki&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;I use &lt;a href=&#34;https://lyz-code.github.io/blue-book/anki/&#34;&gt;&lt;code&gt;anki&lt;/code&gt;&lt;/a&gt; to record the knowledge that I need to have in my mind. The program has a &#34;Stats&#34; tab where you can see your insights of the last years to understand how are you learning. You can also go to the &#34;Browse&#34; tab to sort the cards by created and get an idea of which ones have been the most used decks.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Review what programs you have developed&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Update your identities&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Follow the steps of &lt;a href=&#34;https://lyz-code.github.io/blue-book/identities/#identity-management&#34;&gt;identity management&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;year-reviews&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/year_reviews/&#34;&gt;Year reviews&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Primera versión de la revisión del 2024.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Fuentes&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.elsaltodiario.com/boletin/balance-2024-socias&#34;&gt;Boletín de socias de El Salto 2024&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.elsaltodiario.com/fotografia/imagenes-un-ano-no-se-pudo-parar-genocidio&#34;&gt;Fotografías de un año en el que no se pudo parar el genocidio&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.elsaltodiario.com/boletin/diciembre-2024&#34;&gt;Boletín de diciembre de El Salto 2024&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.elsaltodiario.com/feminismos/siete-palabras-entender-feminismos-2024&#34;&gt;Siete palabras para entender feminismos 2024&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Fascismo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;En 2024, a nivel estatal la extrema derecha avanzó posiciones y cuotas de poder, pero las movilizaciones masivas por la vivienda, contra el modelo turístico y la gestión de la dana desafiaron abiertamente su relato del mundo y su reparto de culpas.&lt;/p&gt; &lt;p&gt;A nivel mundial la cosa va incluso peor:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;estados unidos, la principal potencia económica y militar del mundo ha vuelto a caer en manos de Trump, un multimillonario sádico, que ha conseguido todo su poder a través de su gigantesco poder mediático y un ejército de trolls, bulos y paramilitares supremacistas vestidos con pasamontañas y fusiles de asalto. Los principales países del mundo ya han caído o están a punto de caer en las redes de esta internacional de la desinformación, respaldada y promocionada a su vez por cuatro de los cinco hombres más ricos del mundo.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Uno de ellos es elon musk, un ser despreciable que tras cargarse twitter está haciendo campaña por las ultraderechas como la alemana afd. - &lt;a href=&#34;https://es.wikipedia.org/wiki/Presidencia_de_Javier_Milei&#34;&gt;en argentina ha estado gobernando javier milei&lt;/a&gt; desde el 10 de diciembre de 2023, básicamente se está cargando el estado de derecho y todos los avances en políticas feministas que se consiguieron con tanto esfuerzo.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Antifascismo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Las resistencias a las ideas que propugna esta coalición mundial neofascista, que culpa a la migración y a los pobres de todos los males, que niega el cambio climático, los derechos LGTBIQ+ y de las mujeres, pasan por otro lado.&lt;/p&gt; &lt;p&gt;Desde El Salto tenemos la convicción de que el resultado de esta contienda se dirimirá en gran parte en el campo de la información, de los medios y las redes sociales. Por eso creemos que es tan importante, ahora más que nunca, contar con medios propios, que no dependan de grandes poderes económicos o intereses partidarios.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Byron Maher&#34; src=&#34;../../img/2024-antifa.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Manifestación antiracista en las calles de Londres.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Vivienda&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Las gigantescas movilizaciones por la vivienda y contra el modelo depredador del turismo que recorrieron 2024 desde las Islas Canarias, pasando por Baleares, Madrid, Barcelona y casi todas las grandes capitales españolas, son una buena demostración de que el final de esta película está abierto. Después de estas demostraciones de fuerza y significado, la vivienda no es más barata, pero son menos las personas que piensan que el problema de fondo son los “inquiokupas”.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Luz Sosa&#34; src=&#34;../../img/2024-vivienda.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Canarias se plantó en el mes de abril ante el turismo de masas en una movilización histórica simultánea en las ocho islas.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Álvaro Minguito&#34; src=&#34;../../img/2024-vivienda-1.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Manifestación contra la especulación inmobiliaria y por el derecho a la vivienda en octubre.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Alberto Astudillo&#34; src=&#34;../../img/2024-vivienda-2.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Los desahucios han continuado durante el 2024, al amparo de la cobertura jurídica ofrecida a los especuladores que trafican con el derecho a la vivienda digna, en contra de lo que establece la Constitución Española.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Álvaro Minguito&#34; src=&#34;../../img/2024-vivienda-3.jpg&#34;/&gt; Un amanecer en el barrio de Lavapiés, mientras el vecindario espera un nuevo desahucio en su calle, que finalmente se ejecutó, dejando a otra familia en la calle.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Cambio climático&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;La Dana&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Similar lucha por el discurso y reparto de culpas se produjo tras la dana en València, donde los intentos de la ultraderecha de dirigir el debate hacia los saqueos realizados supuestamente por migrantes fueron frustrados por la emocionante respuesta popular para hacer llegar una ayuda que ninguna institución, ni local ni estatal, estaba proporcionando.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Jaime Pérez Rivero&#34; src=&#34;../../img/2025-01-05-dana.jpg&#34;/&gt; Una senyera del Pais Valencià en una ventana de Paiporta, tras el paso de la dana.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Pedro Armestre&#34; src=&#34;../../img/2024-dana-2.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;El cuerpo de un perro flota junto a los restos de cañizo y arboles arrastrados por la Dana a la playa de Pinedo. La pérdida de biodiversidad, víctima y a la vez solución de esta crisis, también está detrás de lo que está ocurriendo. Restaurar la naturaleza es clave para protegernos frente a eventos extremos a la vez que es una oportunidad transformadora para tener unos entornos resilientes y sanos para la biodiversidad y las personas. Para esto se necesitan medidas desde el nivel local hasta el global.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Jose Ángel Sánchez Rocamora&#34; src=&#34;../../img/2024-dana-3.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;No obstante la población valenciana (y la del resto del estado) ha hecho ver el descontento con la mala gestión que hizo el gobierno del PP en la comunidad como se puede ver en la manifestación multitudinaria del 30 de noviembre para pedir la dimisión del president Carlos Mazón.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Feminismo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Este 2024 también ha estado marcado por las luchas feministas: el terremoto mediático y social provocado por las denuncias anónimas de violencia sexual en redes ha trastocado el panorama político, ha revuelto el mundo del cine y del teatro, y sobre todo, ha resquebrajado el armazón de impunidad que recubre las agresiones machistas. Más allá de dónde acabe todo esto, el movimiento feminista ha vuelto a demostrar su enorme potencia de cambio en un sentido opuesto a la agenda de la extrema derecha.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Elisa González&#34; src=&#34;../../img/2024-feminismo.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;El 25 de noviembre, Día Internacional de la Eliminación de la Violencia contra la Mujer, se celebró en medio de una intensa conversación en torno a las violencias sexuales.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Caso Pelicot&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Martin Barzilai&#34; src=&#34;../../img/2025-01-05-dana.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;El 19 de diciembre de 2024 conocimos la sentencia del caso Pelicot. Dominique fue condenado a 20 años, la pena máxima. El Tribunal de Aviñón (Francia) que lo juzgaba lo consideró culpable de un delito de violación agravada contra ahora ya exesposa Gisèle Pelicot. Desde julio de 2011 y hasta octubre de 2020, el hombre utilizó webs de citas para invitar a desconocidos a agredir sexualmente a su entonces esposa, a la que previamente había suministrado una cantidad de ansiolíticos suficiente como para acercarla “al estado de coma”. Los otros casi cincuenta acusados han sido declarados culpables de violación con penas de entre tres y 15 años.&lt;/p&gt; &lt;p&gt;Gisèle también ha hecho alusión a la vergüenza cuando ha explicado por qué todo el mundo la conoce por el apellido de su exmarido y agresor: “Tengo nietos y no quiero que se avergüencen de usar ese apellido. Quiero que estén orgullosos de su abuela. A partir de hoy se recordará a la señora Pelicot y cada vez menos al señor Pelicot”, explicó esta mujer que aunque ha recuperado su apellido tras divorciarse no quiere regalarle el nombre de sus nietos a un violador.&lt;/p&gt; &lt;p&gt;La consigna “la vergüenza debe cambiar de bando” se ha repetido más allá de Francia y tuvo un lugar destacado en las convocatorias del 25 de noviembre, Día por la Eliminación de la Violencia contra las Mujeres.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Caso Errejón&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;El 23 de octubre, el testimonio de una mujer, publicado en la cuenta de la periodista Cristina Fallarás en Instagram corre por las redes. La mujer señala a “un político de Madrid” como un “maltratador psicológico”. En pocas horas, las redes identifican a Íñigo Errejón. El jueves 25 de octubre, Errejón anuncia que abandona la política y esa misma tarde la actriz Elisa Mouliaá presenta una denuncia ante la Policía en la que relata una agresión sexual.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Migración&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;El fin de año además nos arroja otra cifra, no por esperada menos demoledora: la estimación de más de diez mil personas muertas tratando de llegar a nuestro país. Personas que, por mucho que se empeñe una extrema derecha en auge mediático, solo buscaban mejorar en algo sus vidas y que la perdieron por un sistema cruel que denomina a este otro genocidio “crisis migratoria”.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Manuel del Valle&#34; src=&#34;../../img/2024-migracion.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Las fronteras españolas han marcado este 2024 un récord de la vergüenza: 10.457 personas han muerto tratando de alcanzar las costas de la península. Imagen de la manifestación antirracista el pasado 9 de noviembre, Madrid.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Movimientos sociales&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Este año ha sido duro para las okupas en la ciudad de madríd. Se desalojaron el CSO La Ferroviaria y el CSO La Atalaya&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;David F. Sabadell&#34; src=&#34;../../img/2024-atalaya.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Integrantes del CSO La Atalaya sacan materiales que formaban parte de las decenas de actividades que ofrecía el centro social, mientras la zona se encuentra acordonada por agentes de Policía Nacional.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Servicios públicos&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Edu León&#34; src=&#34;../../img/2024-servicios-publicos.jpg&#34;/&gt; Las asambleas de estudiantes piden seguir la reivindicación de tener unos presupuestos que permitan la supervivencia de la universidad pública en una autonomía donde se impulsa más a la enseñanza privada. &lt;strong&gt;Internacional&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Palestina&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;En diciembre, Israel ha enfocado sus ataques sobre los hospitales del norte de Gaza.&lt;/p&gt; &lt;p&gt;ejército que ha llevado a cabo un genocidio que dura ya más de 440 días.&lt;/p&gt; &lt;p&gt;Comenzamos el año con los ojos puestos en Gaza y Cisjordania y pendientes de la vida de cientos de miles de palestinos amenazados en todo el mundo por el estado sionista de Israel. La cosa no ha ido a mejor en estos 12 meses y a este genocidio calculado le han acompañado otras desgracias, como la creciente crisis ambiental con efectos cada vez más recurrentes en todo el planeta, incluida nuestra españita. En Valencia 231 personas han perdido la vida y 4 más permanecen desaparecidas a causa de una dana que arrasó en pocas horas la comunidad, muertes que quizá pudieron haberse evitado si los responsables políticos hubieran actuado con algo de los que se les presupone, vocación de servicio público, en vez de esconder sus miserias y tratar a toda costa judicial de evitar responsabilidades.&lt;/p&gt; &lt;p&gt;Tras la elección de trump el panorama de palestina no ha hecho más que empeorar (aunque harris tampoco tenía pinta que se fuese a mojar lo más mínimo).&lt;/p&gt; &lt;p&gt;No obstante la sociedad está respondiendo como buenamente puede para presionar a sus gobiernos a que paren el genocidio.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Montecruz foto&#34; src=&#34;../../img/2025-01-05-gaza.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;En el mes de mayo, cientos de estudiantes tomaron la Universidad Humboldt de Berlín en apoyo a Gaza.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Dani Gago&#34; src=&#34;../../img/2024-palestina.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;La batalla naval de Vallecas en 2024, con especial recuerdo para Palestina.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Siria&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Laurent Perpigna Iban&#34; src=&#34;../../img/2024-siria.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Miembros árabes de las Fuerzas Democráticas Sirias en el interior del estadio de Rakka, que el Estado Islámico había convertido en prisión. &lt;strong&gt;Honduras&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Edu León&#34; src=&#34;../../img/2024-honduras.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Honduras heredó del narcogobierno de Juan Orlando Hernández la violencia que ejercen de forma estructural la Policía, el Ejército, las maras y los sicarios contratados por las empresas para matar a líderes ambientales. &lt;strong&gt;Corrupción&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;República&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Este año la monarquía ha caído algo en el ideario popular, aunque no lo suficiente.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Sou Harris&#34; src=&#34;../../img/2024-republica.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Momentos de tensión en la visita de los reyes y representantes políticos 5 días después del paso de la Dana en Valencia. La liaron parda porque impidieron que llegase ayuda voluntaria para que pasase l séquito real. No sentó nada bien, por lo que sea.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/year_reviews/#2025&#34;&gt;Cositas del 2025.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Fascismo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;En el acto de toma de posesión del cargo de trump, elon musk hace el saludo nazi.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;elon nazi&#34; src=&#34;x.mp4&#34;/&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Feminismo&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.usnews.com/news/business/articles/2025-01-20/trump-orders-reflect-his-promises-to-roll-back-transgender-protections-and-end-dei-programs&#34;&gt;trump nada más llegar al poder restablece el género de nacimiento a las personas trans y amenaza con terminar los programas de diversidad, inclusión e igualdad&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;life-chores-management&#34;&gt;Life chores management&lt;/h3&gt; &lt;h4 id=&#34;aerc&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aerc/&#34;&gt;aerc&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce aerc email command line client.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://aerc-mail.org/&#34;&gt;aerc&lt;/a&gt; is an email client that runs in your terminal.&lt;/p&gt; &lt;p&gt;Some of its more interesting features include:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Editing emails in an embedded terminal tmux-style, allowing you to check on incoming emails and reference other threads while you compose your replies&lt;/li&gt; &lt;li&gt;Render HTML emails with an interactive terminal web browser, highlight patches with diffs, and browse with an embedded less session&lt;/li&gt; &lt;li&gt;Vim-style keybindings and ex-command system, allowing for powerful automation at a single keystroke&lt;/li&gt; &lt;li&gt;First-class support for working with git &amp;amp; email&lt;/li&gt; &lt;li&gt;Open a new tab with a terminal emulator and a shell running for easy access to nearby git repos for parallel work&lt;/li&gt; &lt;li&gt;Support for multiple accounts, with IMAP, Maildir, Notmuch, Mbox and JMAP backends. Along with IMAP, JMAP, SMTP, and sendmail transfer protocols.&lt;/li&gt; &lt;li&gt;Asynchronous IMAP and JMAP support ensures the UI never gets locked up by a flaky network.&lt;/li&gt; &lt;li&gt;Efficient network usage - aerc only downloads the information which is necessary to present the UI, making for a snappy and bandwidth-efficient experience&lt;/li&gt; &lt;li&gt;Email threading (with and/or without IMAP server support).&lt;/li&gt; &lt;li&gt;PGP signing, encryption and verification using GNUpg.&lt;/li&gt; &lt;li&gt;100% free and open source software!&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://git.sr.ht/~rjarry/aerc/tree/0.21.0/item/README.md&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Source&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Download the &lt;a href=&#34;https://git.sr.ht/~rjarry/aerc&#34;&gt;latest version&lt;/a&gt; Compile it with the repo instructions&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Debian&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The debian version is very old, compile it directly&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;aerc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Documentation&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The docs are few and hard to read online, but there are throughout in local.&lt;/p&gt; &lt;p&gt;If you&#39;re lost you can always run again the tutorial with &lt;code&gt;:help tutorial&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Configuration&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;On its first run, aerc will copy the default config files to &lt;code&gt;~/.config/aerc&lt;/code&gt; on Linux. When you start the program for the first time a wizard will configure an account and start up the tutorial.&lt;/p&gt; &lt;p&gt;Read &lt;a href=&#34;https://bence.ferdinandy.com/2023/07/20/email-in-the-terminal-a-complete-guide-to-the-unix-way-of-email/#sending-msmtpq&#34;&gt;Bence&lt;/a&gt; post, it&#39;s a nice guideline.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://bence.ferdinandy.com/2023/07/20/email-in-the-terminal-a-complete-guide-to-the-unix-way-of-email/#notmuch&#34;&gt;notmuch&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Notmuch can be used directly as a backend for several email clients, including alot, dodo, Emacs, vim and (more importantly for us) aerc. While it can be used on its own, we are going to use it for its search index, and ability to seamlessly operate over multiple accounts&#39; maildir folder. This will provide us with the ability to search all of our email regardless of account, and to show a unified overview of certain folders, e.g. a unified inbox. If you are only setting this up for a single account, I still recommend using notmuch for its search capabilities.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://frostyx.cz/posts/synchronize-your-2fa-gmail-with-mbsync&#34;&gt;Gmail&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If &lt;a href=&#34;https://frostyx.cz/posts/synchronize-your-2fa-gmail-with-mbsync&#34;&gt;these guidelines&lt;/a&gt; don&#39;t work, try &lt;a href=&#34;https://bence.ferdinandy.com/2023/07/20/email-in-the-terminal-a-complete-guide-to-the-unix-way-of-email/#oauth-mailctl&#34;&gt;this others&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Monitorization&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you are using the mailsync scripts proposed above or on Bence&#39;s post you can check if the service failed with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;groups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;email&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;MailsyncError&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;count_over_time({user_service_name=~&#34;mailsync-.*&#34;} |= `Failed` [15m]) &amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;Error&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;syncing&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;the&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;email&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;service&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.user_service_name&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;at&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.host}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;It assumes that you have the &lt;code&gt;user_service_name&lt;/code&gt; label defined in your logs. I create them with &lt;a href=&#34;https://lyz-code.github.io/blue-book/vector/&#34;&gt;vector&lt;/a&gt; with the next config:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;transforms&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;journald_labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;remap&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;inputs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;journald_filter&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;.service_name = ._SYSTEMD_UNIT || &#34;unknown&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;.user_service_name = .USER_UNIT || ._SYSTEMD_USER_UNIT || &#34;unknown&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;aerc&lt;/code&gt; has many commands that can be bound to keybindings, to see them all check &lt;code&gt;man 1 aerc&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Main page&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;c-p&gt;, &lt;c-n&gt;: Cycles to the previous or next tab&lt;/c-n&gt;&lt;/c-p&gt;&lt;/li&gt; &lt;li&gt;k, j: Scrolls up and down between messages&lt;/li&gt; &lt;li&gt;&lt;c-u&gt;, &lt;c-d&gt;: Scrolls half a page up or down&lt;/c-d&gt;&lt;/c-u&gt;&lt;/li&gt; &lt;li&gt;g, G: Selects the first or last message, respectively&lt;/li&gt; &lt;li&gt;K, J: Switches between folders in the sidebar&lt;/li&gt; &lt;li&gt;&lt;enter&gt;: Opens the selected message&lt;/enter&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;You can also search the selected folder with /, or filter with . When searching you can use n and p to jump to the next and previous result. Filtering hides any non-matching message.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Message viewer&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Press &lt;enter&gt; to open a message. By default, the message viewer will display your message using less(1). This should also have familiar, vim-like keybindings for scrolling around in your message.&lt;/enter&gt;&lt;/p&gt; &lt;p&gt;Multipart messages (messages with attachments, or messages with several alternative formats) show a part selector on the bottom of the message viewer.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;c-k&gt;, &lt;c-j&gt;: Cycle between parts of a multipart message&lt;/c-j&gt;&lt;/c-k&gt;&lt;/li&gt; &lt;li&gt;q: Close the message viewer&lt;/li&gt; &lt;li&gt;f: next message&lt;/li&gt; &lt;li&gt;b: previous message&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;To show HTML messages, uncomment the text/html filter in your aerc.conf file (which is probably in ~/.config/aerc/) and install its dependencies: w3m and dante-utils.&lt;/p&gt; &lt;p&gt;You can also do many tasks you could do in the message list from here, like replying to emails, deleting the email, or view the next and previous message (J and K).&lt;/p&gt; &lt;p&gt;Some interesting commands are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;:unsubscribe&lt;/code&gt;: Attempt to automatically unsubscribe the user from the mailing list through use of the List-Unsubscribe header. If supported, aerc may open a compose window pre-filled with the unsubscribe information or open the unsubscribe URL in a web browser.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Composing messages&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;C: Compose a new message&lt;/li&gt; &lt;li&gt;rr: Reply-all to a message&lt;/li&gt; &lt;li&gt;rq: Reply-all to a message, and pre-fill the editor with a quoted version of the message being replied to&lt;/li&gt; &lt;li&gt;Rr: Reply to a message&lt;/li&gt; &lt;li&gt;Rq: Reply to a message, and pre-fill the editor with a quoted version of the message being replied to&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The message composer will appear. You should see To, From, and Subject lines, as well as your $EDITOR. You can use &lt;tab&gt; or &lt;c-j&gt; and &lt;c-k&gt; to cycle between these fields (tab won&#39;t cycle between fields once you enter the editor, but &lt;c-j&gt; and &lt;c-k&gt; will).&lt;/c-k&gt;&lt;/c-j&gt;&lt;/c-k&gt;&lt;/c-j&gt;&lt;/tab&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://aerc-mail.org/&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://git.sr.ht/~rjarry/aerc&#34;&gt;Source&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://man.sr.ht/~rjarry/aerc/&#34;&gt;Docs&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://todo.sr.ht/~rjarry/aerc?__goaway_challenge=meta-refresh&amp;amp;__goaway_id=7efb941c2542b6ec58b84a4b88e1c20b&#34;&gt;Issues&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Interesting configurations&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://bence.ferdinandy.com/2023/07/20/email-in-the-terminal-a-complete-guide-to-the-unix-way-of-email/#sending-msmtpq&#34;&gt;Bence post&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.acarg.ch/posts/aerc-email-setup/&#34;&gt;Acarg post&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://drewdevault.com/2021/05/17/aerc-with-mbsync-postfix.html&#34;&gt;Drew post&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;himalaya&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/beancount/&#34;&gt;himalaya&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/beancount/#writing-an-importer&#34;&gt;Writing an importer.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;NOTE: since 3.0.0 the importers need to be done with &lt;a href=&#34;https://github.com/beancount/beangulp?tab=readme-ov-file&#34;&gt;&lt;code&gt;beangulp&lt;/code&gt;&lt;/a&gt;. I&#39;ve tried using it but found it confusing so I fell back to 2.x e&lt;/p&gt; &lt;p&gt;Check a list of already existing importers &lt;a href=&#34;https://tariochbctools.readthedocs.io/en/latest/importers.html#&#34;&gt;here&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Once you have your importer built up you might want to spice it up with &lt;a href=&#34;https://github.com/beancount/smart_importer/?tab=readme-ov-file&#34;&gt;smart_importer&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/himalaya/#configure-gpg&#34;&gt;Configure GPG.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Himalaya relies on cargo features to enable gpg. You can see the default enabled features in the &lt;a href=&#34;https://github.com/pimalaya/himalaya/blob/master/Cargo.toml#L18&#34;&gt;Cargo.toml&lt;/a&gt; file. As of 2025-01-27 the &lt;code&gt;pgp-commands&lt;/code&gt; is enabled.&lt;/p&gt; &lt;p&gt;You only need to add the next section to your config:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;na&#34;&gt;pgp.type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;commands&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;And then you can use both the cli and the vim plugin with gpg. Super easy&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;dawarich&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/instant_messages_management/&#34;&gt;dawarich&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add interesting article to merge all protocols under matrix.&lt;/p&gt; &lt;p&gt;You can &lt;a href=&#34;https://technicallyrural.ca/2021/04/05/unify-signal-whatsapp-and-sms-in-a-personal-matrix-server-part-1-matrix/&#34;&gt;use bridges to merge all into matrix&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce dawarich.&lt;/p&gt; &lt;p&gt;Dawarich is a self-hostable alternative to Google Location History (Google Maps Timeline)&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://dawarich.app/docs/intro/#setup-your-dawarich-instance&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Tweak the &lt;a href=&#34;https://github.com/Freika/dawarich/blob/master/docker/docker-compose.yml&#34;&gt;official docker-compose&lt;/a&gt; keeping in mind:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;To configure the &lt;a href=&#34;https://dawarich.app/docs/tutorials/reverse-proxy&#34;&gt;&lt;code&gt;APPLICATION_HOST&lt;/code&gt;&lt;/a&gt; if you&#39;re using a reverse proxy&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Then run &lt;code&gt;docker compose up&lt;/code&gt;. You can now visit your Dawarich instance at &lt;a href=&#34;http://localhost:3000&#34;&gt;http://localhost:3000&lt;/a&gt; or http://&lt;your-server-ip&gt;:3000. The default credentials are &lt;code&gt;demo@dawarich.app&lt;/code&gt; and &lt;code&gt;password&lt;/code&gt;&lt;/your-server-ip&gt;&lt;/p&gt; &lt;p&gt;Go to your account and change the default account and password.&lt;/p&gt; &lt;p&gt;Be careful not to upgrade with watchtower, the devs say that it&#39;s not safe yet to do so.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Not there yet&lt;/strong&gt; - &lt;a href=&#34;https://github.com/Freika/dawarich/issues/1071&#34;&gt;Immich photos are not well shown&lt;/a&gt;: This happens when opening the map, or selecting one of the buttons &#34;Yesterday&#34;, &#34;Last 7 Days&#34; or &#34;Last month&#34;. If you select the same date range through the date-pickers, the photos are shown. - &lt;a href=&#34;https://github.com/Freika/dawarich/issues/1261&#34;&gt;Support import of OSMand+ favourites gpx&lt;/a&gt; - &lt;a href=&#34;https://github.com/Freika/dawarich/issues/65&#34;&gt;OpenID/Oauth support&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://dawarich.app/&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://dawarich.app/docs/intro/&#34;&gt;Docs&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/Freika/dawarich&#34;&gt;Source&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/dawarich/#how-to-see-the-coordinates-of-a-point&#34;&gt;How to see the coordinates of a point.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You need to enable the &#34;Points&#34; layer, which is on the layers menu at the top right of the map.&lt;/p&gt; &lt;p&gt;Then if you click on one point you can get the coordinates&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;signal&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/signal/&#34;&gt;Signal&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/signal/#signal-bots&#34;&gt;Signal bots.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To write signal bots you can use &lt;a href=&#34;https://github.com/JeremyGDiamond/signal-info-bot&#34;&gt;this library&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/k9/#how-to-set-a-master-password&#34;&gt;How to set a master password.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can&#39;t, it&#39;s not supported and it doesn&#39;t look that it will (&lt;a href=&#34;https://forum.k9mail.app/t/password-protection-for-launch-of-k9/6871/11&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;https://forum.k9mail.app/t/can-i-password-protect-app-on-startup/6755/6&#34;&gt;2&lt;/a&gt;)&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add note on AWS use.&lt;/p&gt; &lt;p&gt;It runs on AWS. On October 2025 there was an AWS outage and signal fell&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;content-management&#34;&gt;Content Management&lt;/h3&gt; &lt;h4 id=&#34;jellyfin&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/moonlight/&#34;&gt;Jellyfin&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add note on apollo.&lt;/p&gt; &lt;p&gt;Also checkout &lt;a href=&#34;https://github.com/ClassicOldSong/Apollo&#34;&gt;apollo&lt;/a&gt; a sunshine fork.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/#rollback&#34;&gt;How to rollback.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Copy the &lt;code&gt;/srv/jellyfin/app&lt;/code&gt; directory to &lt;code&gt;bk.app&lt;/code&gt; and then restore the directory from backup.&lt;/p&gt; &lt;p&gt;If the permissions have gone amiss you&#39;ll need to fix them before you start the server or you&#39;ll get an &lt;code&gt;attempt to write a readonly database&lt;/code&gt; error feat(linux_snippets#Resize an image): Resize an image&lt;/p&gt; &lt;p&gt;To resize an image, you can use the convert command from ImageMagick. For example, to resize an image named input.jpg to have a width of 800 pixels while maintaining the aspect ratio, use the following command:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;convert&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;input.jpg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-resize&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;800x&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;input_resized.jpg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can also specify both width and height if you want to resize the image to specific dimensions:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;convert&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;input.jpg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-resize&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;800x600&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;input_resized_exact.jpg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;book-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/ombi/&#34;&gt;Book Management&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/book_management/#convert-pdf-to-epub&#34;&gt;Convert images based pdf to epub.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;NOTE: before proceeding inspect the next tools that use AI so it will probably give a better output:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/opendatalab/MinerU&#34;&gt;MinerU&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/VikParuchuri/marker&#34;&gt;marker&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/docling-project/docling&#34;&gt;docling&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://olmocr.allenai.org/&#34;&gt;olmocr&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;If the pdf is based on images&lt;/p&gt; &lt;p&gt;Then you need to use OCR to extract the text.&lt;/p&gt; &lt;p&gt;First, convert the PDF to images:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pdftoppm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-png&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;input.pdf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;page
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Apply OCR to your PDF&lt;/p&gt; &lt;p&gt;Use &lt;code&gt;tesseract&lt;/code&gt; to extract text from each image:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;img&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;page-*.png&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;tesseract&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$img&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;img&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;%.png&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;eng
&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This produces &lt;code&gt;page-1.txt&lt;/code&gt;, &lt;code&gt;page-2.txt&lt;/code&gt;, etc.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ombi/#protect-ombi-behind-authentik&#34;&gt;Protect ombi behind authentik.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This option allows the user to select a HTTP header value that contains the desired login username.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Note that if the header value is present and matches an existing user, default authentication is bypassed - use with caution.&lt;/p&gt; &lt;/blockquote&gt; &lt;p&gt;This is most commonly utilized when Ombi is behind a reverse proxy which handles authentication. For example, if using Authentik, the X-authentik-username HTTP header which contains the logged in user&#39;s username is set by Authentik&#39;s proxy outpost.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;book-drm&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/book_drm/&#34;&gt;Book DRM&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: How to remove DRM from ebooks.&lt;/p&gt; &lt;p&gt;To remove the DRM from ebooks you can use &lt;a href=&#34;https://github.com/noDRM/DeDRM_tools&#34;&gt;DeDRM_tools&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You need to download &lt;a href=&#34;https://github.com/noDRM/DeDRM_tools/releases&#34;&gt;the latest release&lt;/a&gt;, and follow the instructions of the README.md of the zip file.o&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Once the plugin is installed, you can import the books you want to remove the DRM from. In theory the plugin only works on import and not on convert, but I&#39;ve also used the convert tool to make sure it&#39;s a different file.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;beets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/news_management/&#34;&gt;Beets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add forensic architecture.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://forensic-architecture.org/&#34;&gt;Forensic architecture&lt;/a&gt;: Forensic Architecture (FA) is a research agency based at Goldsmiths, University of London. Our mandate is to develop, employ, and disseminate new techniques, methods, and concepts for investigating state and corporate violence. Our team includes architects, software developers, filmmakers, investigative journalists, scientists, and lawyers.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/beets/#plugins&#34;&gt;Add plugins.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://beets.readthedocs.io/en/stable/plugins/chroma.html&#34;&gt;Chromaprint&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Programmatically interact with beets&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;There is the &lt;a href=&#34;https://beets.readthedocs.io/en/v1.3.18/dev/api.html&#34;&gt;python api reference&lt;/a&gt; but I don&#39;t see how to import for example.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;knowledge-management&#34;&gt;Knowledge Management&lt;/h3&gt; &lt;h4 id=&#34;anki&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/anki/&#34;&gt;Anki&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/anki/#file-location&#34;&gt;File location.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;On Linux:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;recent Anki versions store your user data in &lt;code&gt;~/.local/share/Anki2&lt;/code&gt;, or &lt;code&gt;$XDG_DATA_HOME/Anki2&lt;/code&gt; if you have set a custom data path.&lt;/li&gt; &lt;li&gt;Anki’s launcher is installed in &lt;code&gt;/usr/local/share/anki&lt;/code&gt;&lt;/li&gt; &lt;li&gt;When you install/update Anki with the launcher, it downloads support files and places them in &lt;code&gt;~/.local/share/AnkiProgramFiles&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Removing that folder will cause the launcher to behave like a fresh install.&lt;/p&gt; &lt;p&gt;The AnkiProgramFiles contains all the files needed to run Anki aside from the launcher.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;torrent-management&#34;&gt;Torrent management&lt;/h3&gt; &lt;h4 id=&#34;qbittorrent&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/qbittorrent/&#34;&gt;qBittorrent&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/qbittorrent/#metrics-monitorisation&#34;&gt;Metrics monitorisation.&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;health&#34;&gt;Health&lt;/h2&gt; &lt;h3 id=&#34;silence&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/silence/&#34;&gt;Silence&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/silence/#resources&#34;&gt;Introduce the Right to quiet collective.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://quiet.org/&#34;&gt;Right to quiet&lt;/a&gt;: The Right to Quiet Society for Soundscape Awareness and Protection was founded in Vancouver, British Columbia in 1982 as a charitable organization with the mission of raising public awareness of the detrimental effects of noise on health; promoting awareness of noise pollution and the dangers of noise to our physical, emotional, and spiritual wellbeing; working for noise reduction through better regulation and enforcement; encouraging responsible behaviour regarding noise; advocating for manufacturing quieter products; and fostering recognition of the right to quiet as a basic human right, rather than as an amenity for the affluent.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://quiet.org/resources/&#34;&gt;Right to quiet resources&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;technology&#34;&gt;Technology&lt;/h2&gt; &lt;h3 id=&#34;coding&#34;&gt;Coding&lt;/h3&gt; &lt;h4 id=&#34;bash-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/&#34;&gt;Bash snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add context switches column meanings.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;UID: The real user identification number of the task being monitored.&lt;/li&gt; &lt;li&gt;USER: The name of the real user owning the task being monitored.&lt;/li&gt; &lt;li&gt;PID: The identification number of the task being monitored.&lt;/li&gt; &lt;li&gt;cswch/s: Total number of voluntary context switches the task made per second. A voluntary context switch occurs when a task blocks because it requires a resource that is unavailable.&lt;/li&gt; &lt;li&gt;nvcswch/s: Total number of non voluntary context switches the task made per second. A involuntary context switch takes place when a task executes for the duration of its time slice and then is forced to relinquish the processor.&lt;/li&gt; &lt;li&gt;Command: The command name of the task.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pdm&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/lazyvim/&#34;&gt;PDM&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/lazyvim/#load-a-plugin-on-startup&#34;&gt;Load a plugin on startup.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can &lt;a href=&#34;https://lazy.folke.io/spec/examples&#34;&gt;define the &lt;code&gt;lazy = false&lt;/code&gt; in your plugin spec&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;-- the colorscheme should be available when starting Neovim&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;folke/tokyonight.nvim&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;lazy&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- make sure we load this during startup if it is your main colorscheme&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;diff --git a/docs/linux/wireguard.md b/docs/linux/wireguard.md index d69f315a8e..6ccbaa011c 100644 --- a/docs/linux/wireguard.md +++ b/docs/linux/wireguard.md @@ -16,41 +16,42 @@ VPN solution in the industry.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Suggest to check uv.&lt;/p&gt; &lt;p&gt;Maybe use &lt;a href=&#34;https://astral.sh/blog/uv&#34;&gt;uv&lt;/a&gt; instead (although so far I&#39;m still using &lt;code&gt;pdm&lt;/code&gt;)&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;vim-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_snippets/&#34;&gt;Vim Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_snippets/#search-for-different-strings-in-the-same-search-query&#34;&gt;Search for different strings in the same search query.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;* DONE\|* REJECTED\|* DUPLICATED
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/pipx/#upgrading-python-version-of-all-your-pipx-packages&#34;&gt;Upgrading python version of all your pipx packages.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you upgrade the main python version and remove the old one (a dist upgrade) then you won&#39;t be able to use the installed packages.&lt;/p&gt; &lt;p&gt;If you&#39;re lucky enough to have the old one you can use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pipx reinstall-all --python &amp;lt;the Python executable file&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Otherwise you need to export all the packages with &lt;code&gt;pipx list --json &amp;gt; ~/pipx.json&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Then reinstall one by one:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-ux
&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-e&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;~/pipx.json&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;~/pipx.json&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;jq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;.venvs[].metadata.main_package.package_or_url&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;pipx&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$p&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The problem is that this method does not respect the version constrains nor the injects, so you may need to debug each package a bit.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/forgejo/#push-to-a-forgejo-docker-registry&#34;&gt;Push to a forgejo docker registry.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Login to the container registry&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To push an image or if the image is in a private registry, you have to authenticate:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;login&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;forgejo.example.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you are using 2FA or OAuth use a personal access token instead of the password.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Image naming convention&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Images must follow this naming convention:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;{registry}/{owner}/{image}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;When building your docker image, using the naming convention above, this looks like:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;build&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;registry&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;/&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;owner&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;/&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;image&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;:&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;tag&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.

docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tag&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;some-existing-image&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;:&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;tag&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;registry&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;/&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;owner&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;/&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;image&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;:&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;tag&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where your registry is the domain of your forgejo instance (e.g. forgejo.example.com). For example, these are all valid image names for the owner testuser:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;forgejo.example.com/testuser/myimage&lt;/li&gt; &lt;li&gt;forgejo.example.com/testuser/my-image&lt;/li&gt; &lt;li&gt;forgejo.example.com/testuser/my/image&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;NOTE: The registry only supports case-insensitive tag names. So image:tag and image:Tag get treated as the same image and tag.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Push an image&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Push an image by executing the following command:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;forgejo.example.com/&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;owner&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;/&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;image&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;:&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;tag&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;forgejo.example.com/testuser/myimage:latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/pipx/#installing-all-the-binaries-the-application-installs&#34;&gt;Installing all the binaries the application installs.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If the package installs more than one binary (for example &lt;code&gt;ansible&lt;/code&gt;), you need to use the &lt;code&gt;--install-deps&lt;/code&gt; flag&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pipx&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--install-deps&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ansible
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_snippets/#create-quickmarks-across-files&#34;&gt;Create quickmarks across files.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use capital letters for the mark.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;http://vim.wikia.com/wiki/Using_marks&#34;&gt;http://vim.wikia.com/wiki/Using_marks&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Marks can span across files. To use such marks one has to use upper-case registers i.e. A-Z. Lower-case registers are used only within files and do not span files. That&#39;s to say, if you were to set a mark in a file foo.c in register &#34;a&#34; and then move to another file and hit &#39;a, the cursor will not jump back to the previous location. If you want a mark which will take you to a different file then you will need to use an upper-case register. For example, use mA instead of ma.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;configure-docker-to-host-the-application&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/lua/&#34;&gt;Configure Docker to host the application&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/lua/#syntax&#34;&gt;Syntax rules.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Boolean operations&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Not equal operation&lt;/strong&gt; In Lua, you can perform a &#34;not equal&#34; comparison using the &lt;code&gt;~=&lt;/code&gt; operator:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;~=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;-- true if a is not equal to b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;List operations&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Length of a list&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;current_slide&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;

&lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current_slide&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;-- code&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#configuration&#34;&gt;Configure gitea.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Check the &lt;a href=&#34;https://docs.gitea.com/administration/config-cheat-sheet&#34;&gt;configuration sheet&lt;/a&gt; or the &lt;a href=&#34;https://github.com/go-gitea/gitea/blob/release/v1.23/custom/conf/app.example.ini&#34;&gt;default values&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#upgrade-the-gitea-actions-runner&#34;&gt;Upgrade the gitea actions runner.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Check in &lt;a href=&#34;https://gitea.com/gitea/act_runner/releases&#34;&gt;the releases&lt;/a&gt; the last version and the changelog&lt;/li&gt; &lt;li&gt;Deploy the new version&lt;/li&gt; &lt;li&gt;Restart the service&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#upgrade&#34;&gt;Upgrade gitea.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Check the Changelog for breaking changes&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To make Gitea better, some breaking changes are unavoidable, especially for big milestone releases. Before upgrading, please read the &lt;a href=&#34;https://blog.gitea.com/&#34;&gt;Changelog on Gitea blog&lt;/a&gt; and check whether the breaking changes affect your Gitea instance.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Verify there are no deprecated configuration options&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;New versions of Gitea often come with changed configuration syntax or options which are usually displayed for at least one release cycle inside at the top of the Site Administration panel. If these warnings are not resolved, Gitea may refuse to start in the following version.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Make a backup&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://docs.gitea.com/installation/upgrade-from-gitea#upgrade-with-docker&#34;&gt;Upgrade from docker&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;docker pull the latest Gitea release.&lt;/li&gt; &lt;li&gt;Stop the running instance, backup data.&lt;/li&gt; &lt;li&gt;Use docker or docker-compose to start the newer Gitea Docker container.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://docs.gitea.com/installation/upgrade-from-gitea#upgrade-from-binary&#34;&gt;Upgrade from binary&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;A script automating the following steps for a deployment on Linux can be found at &lt;a href=&#34;https://raw.githubusercontent.com/go-gitea/gitea/refs/heads/release/v1.23/contrib/upgrade.sh&#34;&gt;contrib/upgrade.sh&lt;/a&gt; in Gitea&#39;s source tree.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Download the latest Gitea binary to a temporary directory.&lt;/li&gt; &lt;li&gt;Stop the running instance, backup data.&lt;/li&gt; &lt;li&gt;Replace the installed Gitea binary with the downloaded one.&lt;/li&gt; &lt;li&gt;Start the Gitea instance.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Read the script to see what it&#39;s going to do. To upgrade to &lt;code&gt;1.20.5&lt;/code&gt; you can use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;./update.sh&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;.20.5
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you have a different home directory for gitea you can set&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;giteahome&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/var/gitea&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;./update.sh&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;.20.5
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#limit-the-access-of-a-docker-on-a-server-to-the-access-on-the-docker-of-another-server&#34;&gt;Limit the access of a docker on a server to the access on the docker of another server.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;WARNING: I had issues with this path and I ended up not using docker swarm networks.&lt;/p&gt; &lt;p&gt;If you want to restrict access to a docker (running on server 1) so that only another specific docker container running on another server (server 2) can access it. You need more than just IP-based filtering between hosts. The solution is then to:&lt;/p&gt; &lt;ol&gt; &lt;li&gt; &lt;p&gt;Create a Docker network that spans both hosts using Docker Swarm or a custom overlay network.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;strong&gt;Use Docker&#39;s built-in DNS resolution&lt;/strong&gt; to allow specific container-to-container communication.&lt;/p&gt; &lt;/li&gt; &lt;/ol&gt; &lt;p&gt;Here&#39;s a step-by-step approach:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;1. Set up Docker Swarm (if not already done)&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;On server 1:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;swarm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;init&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--advertise-addr&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;ip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;of&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;server&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This will output a command to join the swarm. Run that command on server 2.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;2. Create an overlay network&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;network&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;create&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--driver&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;overlay&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--attachable&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;of&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;the&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;network&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;3. Update the docker compose on server 1&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;magine for example that we want to deploy &lt;a href=&#34;https://lyz-code.github.io/blue-book/wg-easy/&#34;&gt;wg-easy&lt;/a&gt;.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;wg-easy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ghcr.io/wg-easy/wg-easy:latest&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;container_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;wg-easy&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;networks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;wg&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;&amp;lt;name of the network&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Add the overlay network&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;wireguard:/etc/wireguard&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/lib/modules:/lib/modules:ro&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ports&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;51820:51820/udp&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# - &#34;127.0.0.1:51821:51821/tcp&#34; # Don&#39;t expose the http interface, it will be accessed from within the docker network&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;restart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;unless-stopped&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cap_add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;NET_ADMIN&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;SYS_MODULE&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;sysctls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;net.ipv4.ip_forward=1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;net.ipv4.conf.all.src_valid_mark=1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;net.ipv6.conf.all.disable_ipv6=1&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;networks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;wg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Your existing network config&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;name of the network&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;external&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Reference the overlay network created above&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;4. On server 2, create a Docker Compose file for your client container&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;wg-client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;your-client-image&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;container_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;wg-client&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;networks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;&amp;lt;name of the network&amp;gt;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Other configuration for your client container&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;networks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;name of the network&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;external&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Reference the same overlay network&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;5. Access the WireGuard interface from the client container&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Now, from within the client container on server 2, you can access the WireGuard interface using the container name:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;http://wg-easy:51821
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This approach ensures that:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;The WireGuard web interface is not exposed to the public (not even localhost on server 1)&lt;/li&gt; &lt;li&gt;Only containers on the shared overlay network can access it&lt;/li&gt; &lt;li&gt;The specific container on server 2 can access it using Docker&#39;s internal DNS&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;strong&gt;Testing the network is well set&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You may be confused if the new network is not shown on server 2 when running &lt;code&gt;docker network ls&lt;/code&gt; but that&#39;s normal. Server 2 is a swarm worker node. The issue with not seeing the overlay network on server 2 is actually expected behavior - worker nodes cannot list or manage networks directly. However, even though you can&#39;t see them, containers on the server 2 can still connect to the overlay network when properly configured.&lt;/p&gt; &lt;p&gt;To see that the swarm is well set you can use &lt;code&gt;docker node ls&lt;/code&gt; on server 1 (you&#39;ll see an error on server 2 as it&#39;s a worker node)&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Weird network issues with swarm overlays&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;I&#39;ve seen cases where after a server reboot you need to remove the overlay network from the docker compose and then add it again.&lt;/p&gt; &lt;p&gt;After many hours of debugging I came with the patch of removing the overlay network from the docker-compose and attaching it with the systemd service&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[Unit]
Description=wg-easy
Requires=docker.service
After=docker.service

[Service]
Restart=always
User=root
Group=docker
WorkingDirectory=/data/apps/wg-easy
TimeoutStartSec=100
RestartSec=2s
ExecStart=/usr/bin/docker compose -f docker-compose.yaml up

ExecStartPost=/bin/bash -c &#39;\
    sleep 30; \
    /usr/bin/docker network connect wg-easy wg-easy; \
&#39;
ExecStop=/usr/bin/docker compose -f docker-compose.yaml down

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#configure-triggers-not-to-push-to-a-branch&#34;&gt;Configure triggers not to push to a branch.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;There is now a branches-ignore option:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;push&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;branches-ignore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;main&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#not-there-yet&#34;&gt;Not there yet.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/go-gitea/gitea/issues/32662&#34;&gt;Being able to run two jobs on the same branch&lt;/a&gt;: It will be implemented with &lt;a href=&#34;https://github.com/go-gitea/gitea/issues/24769&#34;&gt;concurrency&lt;/a&gt; with &lt;a href=&#34;https://github.com/go-gitea/gitea/pull/32751&#34;&gt;this pr&lt;/a&gt;. This behavior &lt;a href=&#34;https://github.com/go-gitea/gitea/pull/25716&#34;&gt;didn&#39;t happen before 2023-07-25&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#push-an-image-with-different-architectures-after-building-it-in-different-instances&#34;&gt;Push an image with different architectures after building it in different instances.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To push both an &lt;strong&gt;ARM&lt;/strong&gt; and &lt;strong&gt;AMD&lt;/strong&gt; Docker image to &lt;strong&gt;Docker Hub&lt;/strong&gt;, from two separate machines (e.g., an ARM-based and an AMD-based instance), follow these steps:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Tag the image correctly on each architecture&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;On &lt;strong&gt;each instance&lt;/strong&gt;, build your image as normal, but &lt;strong&gt;tag it with a platform-specific suffix&lt;/strong&gt;, like &lt;code&gt;myuser/myimage:arm64&lt;/code&gt; or &lt;code&gt;myuser/myimage:amd64&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;On the ARM machine:&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;build&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;myuser/myimage:arm64&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.
docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;myuser/myimage:arm64
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;On the AMD machine:&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;build&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;myuser/myimage:amd64&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.
ocker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;myuser/myimage:amd64
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Create a multi-architecture manifest (on one machine)&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you want users to pull the image without worrying about the platform (e.g., just &lt;code&gt;docker pull myuser/myimage:latest&lt;/code&gt;), you can create and push a &lt;strong&gt;manifest list&lt;/strong&gt; that combines the two:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Choose either machine to run this (after both images are pushed):&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;manifest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;create&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;myuser/myimage:latest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;--amend&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;myuser/myimage:amd64&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;--amend&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;myuser/myimage:arm64

docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;manifest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;myuser/myimage:latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Add note to run gitea actions runners in kubernetes.&lt;/p&gt; &lt;p&gt;Kubernetes act runner, there is a &lt;a href=&#34;https://gitea.com/gitea/act_runner/issues/264&#34;&gt;stale issue&lt;/a&gt; and &lt;a href=&#34;https://gitea.com/gitea/act_runner/src/branch/main/examples/kubernetes&#34;&gt;an ugly implementation&lt;/a&gt; to run docker in docker inside the kubernetes node.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#push-an-image-with-different-architectures-after-building-it-in-different-instances&#34;&gt;Push an image with different architectures after building it in different instances.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To push both an &lt;strong&gt;ARM&lt;/strong&gt; and &lt;strong&gt;AMD&lt;/strong&gt; Docker image to a Docker registry, from two separate machines (e.g., an ARM-based and an AMD-based instance), you have two options:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Run two different pipelines and then build a manifest&lt;/li&gt; &lt;li&gt;Use &lt;a href=&#34;https://docs.docker.com/build/ci/github-actions/configure-builder/#append-additional-nodes-to-the-builder&#34;&gt;two buildx remotes&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;QEMU was discarted because it took too long to build the images.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#do-a-copy-of-a-list-of-docker-images-in-your-private-registry&#34;&gt;Do a copy of a list of docker images in your private registry.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-euo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pipefail

&lt;span class=&#34;nv&#34;&gt;SCRIPT_DIR&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;dirname&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;BASH_SOURCE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[0]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;pwd&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;:-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;SCRIPT_DIR&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;/bitnami-images.txt&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;TARGET_REGISTRY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;:-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-z&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TARGET_REGISTRY&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Usage: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$0&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; &amp;lt;image_list_file&amp;gt; &amp;lt;target_registry&amp;gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Example: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$0&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; bitnami-images.txt your.docker.registry.org&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;!&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Error: Image list file &#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#39; not found&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

log&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;[&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;date&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;+%Y-%m-%d %H:%M:%S&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;] &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$*&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

extract_image_name_and_tag&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;full_image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$1&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Remove registry prefix to get org/repo:tag&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Examples:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# docker.io/bitnami/discourse:3.4.7 -&amp;gt; bitnami/discourse:3.4.7&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# registry-1.docker.io/bitnami/os-shell:11-debian-11-r95 -&amp;gt; bitnami/os-shell:11-debian-11-r95&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$full_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;~&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;^&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;^/&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;*&lt;span class=&#34;se&#34;&gt;\.&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;^/&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;+/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Contains registry with dot - remove everything up to first /&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;full_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;#*/&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# No registry prefix&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$full_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

pull_and_push_multiarch&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;source_image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$1&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;target_registry&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$2&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;image_name_with_tag
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;image_name_with_tag&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;extract_image_name_and_tag&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;target_image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;target_registry&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;image_name_with_tag&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Processing: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; -&amp;gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=()&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;architectures&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;linux/amd64&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;linux/arm64&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_suffixes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;amd64&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;arm64&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Try to pull and push each architecture&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;!architectures[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;architectures&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_suffix&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_suffixes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Attempting to pull &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pull&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--platform&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$platform&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Successfully pulled &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Tag with architecture-specific tag for manifest creation&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_specific_tag&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;target_image&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_suffix&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tag&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch_specific_tag&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Pushing &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image as &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_specific_tag&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch_specific_tag&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Successfully pushed &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+=(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch_specific_tag&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed to push &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rmi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch_specific_tag&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;⚠️  &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image not available for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; - skipping&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-eq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;❌ No images were successfully pushed for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Create the main tag with proper multi-arch manifest&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-gt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Creating multi-arch manifest for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Remove any existing manifest (in case of retry)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;manifest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;manifest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;create&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Annotate each architecture in the manifest&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;!pushed_images[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_tag&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_suffixes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;manifest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;annotate&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch_tag&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--arch&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--os&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;linux
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Pushing multi-arch manifest to &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;manifest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;✅ Successfully pushed multi-arch image: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;❌ Failed to push manifest for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;❌ Failed to create manifest for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Only one architecture - tag and push directly&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Single architecture available, pushing as &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tag&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[0]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;✅ Successfully pushed single-arch image: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;❌ Failed to push &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Clean up local images to save space&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rmi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-eq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rmi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

main&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Starting multi-architecture image pull and push&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Source list: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Target registry: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TARGET_REGISTRY&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Enable experimental CLI features for manifest commands&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;DOCKER_CLI_EXPERIMENTAL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;enabled

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;total_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;wc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;processed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;successful_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;failed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=()&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;IFS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;image_line&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Skip empty lines and comments&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-z&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;~&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;^&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;:space:&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;*#&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Remove leading/trailing whitespace&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;image_line&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sed&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;s/^[[:space:]]*//;s/[[:space:]]*$//&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-z&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;processed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;processed_images&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$processed_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$total_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;] Processing: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pull_and_push_multiarch&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TARGET_REGISTRY&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;successful_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;successful_images&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;✓ Success: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;failed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+=(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;✗ Failed: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Progress: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$processed_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$total_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; completed&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;----------------------------------------&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Final Summary:&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Total images processed: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$processed_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Successful: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$successful_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;failed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;failed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-gt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed images:&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;  %s\n&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;failed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;🎉 All images processed successfully!&#34;&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

main&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$@&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#migrate-away-from-bitnami&#34;&gt;Migrate away from bitnami.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Bitnami is changing their pull policy making it unfeasible to use their images (More info here: &lt;a href=&#34;https://www.reddit.com/r/selfhosted/comments/1ma5d8t/migrating_away_from_bitnami/&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;https://archive.ph/dIVZk&#34;&gt;2&lt;/a&gt;, &lt;a href=&#34;https://www.reddit.com/r/kubernetes/comments/1mc73s4/bitnami_moving_most_free_container_images_to_a/?chainedPosts=t3_1ma5d8t&#34;&gt;3&lt;/a&gt;), so there is the need to migrate to other image providers.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Which alternative to use&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The migration can be done to the official maintained images (although this &lt;a href=&#34;https://www.reddit.com/r/selfhosted/comments/1ma5d8t/migrating_away_from_bitnami/&#34;&gt;has some disadvantages&lt;/a&gt;) or to any of the common docker image builders:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/home-operations/containers/&#34;&gt;https://github.com/home-operations/containers/&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/linuxserver&#34;&gt;https://github.com/linuxserver&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/11notes&#34;&gt;https://github.com/11notes&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;There is an effort &lt;a href=&#34;https://github.com/bitcompat&#34;&gt;to build a fork of bitnami images&lt;/a&gt; but it has not yet much inertia.&lt;/p&gt; &lt;p&gt;Regarding the alternatives of helm charts, a quick look shown &lt;a href=&#34;https://github.com/groundhog2k/helm-charts/tree/master/charts&#34;&gt;this one&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Infrastructure archeology&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;First you need to know which images are you using, to do that you can:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#clone-al-git-repositories-of-a-series-of-organisations&#34;&gt;Clone al git repositories of a series of organisations&lt;/a&gt; and do a local grep&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes/#search-all-the-container-images-in-use-that-match-a-desired-string&#34;&gt;Search all the container images in use in kubernetes that match a desired string&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/argocd/#recursively-pull-a-copy-of-all-helm-charts-used-by-an-argocd-repository&#34;&gt;Recursively pull a copy of all helm charts used by an argocd repository&lt;/a&gt; and then do a grep.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Create a local copy of the images&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;It&#39;s wise to make a copy of the used images in your local registry to be able to pull the dockers once bitnami does not longer let you.&lt;/p&gt; &lt;p&gt;To do that you can save the used images in a &lt;code&gt;bitnami-images.txt&lt;/code&gt; file and run the next script:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-euo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pipefail

&lt;span class=&#34;nv&#34;&gt;SCRIPT_DIR&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;dirname&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;BASH_SOURCE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[0]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;pwd&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;:-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;SCRIPT_DIR&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;/bitnami-images.txt&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;TARGET_REGISTRY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;:-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-z&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TARGET_REGISTRY&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Usage: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$0&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; &amp;lt;image_list_file&amp;gt; &amp;lt;target_registry&amp;gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Example: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$0&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; bitnami-images.txt registry.cloud.icij.org&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;!&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Error: Image list file &#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#39; not found&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

log&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;[&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;date&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;+%Y-%m-%d %H:%M:%S&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;] &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$*&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

extract_image_name_and_tag&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;full_image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$1&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Remove registry prefix to get org/repo:tag&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Examples:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# docker.io/bitnami/discourse:3.4.7 -&amp;gt; bitnami/discourse:3.4.7&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# registry-1.docker.io/bitnami/os-shell:11-debian-11-r95 -&amp;gt; bitnami/os-shell:11-debian-11-r95&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# registry-proxy.internal.cloud.icij.org/bitnami/minideb:stretch -&amp;gt; bitnami/minideb:stretch&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$full_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;~&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;^&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;^/&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;*&lt;span class=&#34;se&#34;&gt;\.&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;^/&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;+/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Contains registry with dot - remove everything up to first /&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;full_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;#*/&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# No registry prefix&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$full_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

pull_and_push_multiarch&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;source_image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$1&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;target_registry&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$2&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;image_name_with_tag
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;image_name_with_tag&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;extract_image_name_and_tag&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;target_image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;target_registry&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;image_name_with_tag&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Processing: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; -&amp;gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=()&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;architectures&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;linux/amd64&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;linux/arm64&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_suffixes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;amd64&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;arm64&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Try to pull and push each architecture&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;!architectures[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;architectures&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_suffix&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_suffixes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Attempting to pull &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pull&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--platform&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$platform&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Successfully pulled &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Tag with architecture-specific tag for manifest creation&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_specific_tag&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;target_image&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_suffix&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tag&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch_specific_tag&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Pushing &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image as &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_specific_tag&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch_specific_tag&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Successfully pushed &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+=(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch_specific_tag&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed to push &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rmi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch_specific_tag&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;⚠️  &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image not available for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; - skipping&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-eq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;❌ No images were successfully pushed for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Create the main tag with proper multi-arch manifest&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-gt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Creating multi-arch manifest for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Remove any existing manifest (in case of retry)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;manifest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;manifest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;create&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Annotate each architecture in the manifest&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;!pushed_images[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_tag&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_suffixes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;manifest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;annotate&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch_tag&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--arch&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--os&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;linux
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Pushing multi-arch manifest to &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;manifest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;✅ Successfully pushed multi-arch image: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;❌ Failed to push manifest for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;❌ Failed to create manifest for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Only one architecture - tag and push directly&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Single architecture available, pushing as &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tag&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[0]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;✅ Successfully pushed single-arch image: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;❌ Failed to push &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Clean up local images to save space&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rmi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-eq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rmi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

main&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Starting multi-architecture image pull and push&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Source list: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Target registry: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TARGET_REGISTRY&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Enable experimental CLI features for manifest commands&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;DOCKER_CLI_EXPERIMENTAL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;enabled

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;total_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;wc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;processed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;successful_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;failed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=()&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;IFS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;image_line&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Skip empty lines and comments&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-z&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;~&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;^&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;:space:&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;*#&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Remove leading/trailing whitespace&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;image_line&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sed&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;s/^[[:space:]]*//;s/[[:space:]]*$//&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-z&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;processed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;processed_images&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$processed_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$total_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;] Processing: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pull_and_push_multiarch&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TARGET_REGISTRY&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;successful_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;successful_images&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;✓ Success: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;failed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+=(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;✗ Failed: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Progress: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$processed_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$total_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; completed&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;----------------------------------------&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Final Summary:&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Total images processed: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$processed_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Successful: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$successful_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;failed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;failed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-gt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed images:&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;  %s\n&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;failed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;🎉 All images processed successfully!&#34;&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

main&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$@&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Replace a bitnami image with a local one&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you for some reason need to pull &lt;code&gt;bitnami/discourse:3.4.7&lt;/code&gt; and get an error you need instead to pull it from &lt;code&gt;{your_registry}/bitnami/discourse:3.4.7&lt;/code&gt;. If you want to pull a specific architecture you can append it at the end (&lt;code&gt;{your_registry}/bitnami/discourse:3.4.7-amd64&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;If you need to do the changes in an argocd managed kubernetes application search in the &lt;code&gt;values.yaml&lt;/code&gt; or &lt;code&gt;values-{environment}.yaml&lt;/code&gt; files for the &lt;code&gt;image:&lt;/code&gt; string. If it&#39;s not defined you may need to look at the helm chart definition. To do that open the &lt;code&gt;Chart.yaml&lt;/code&gt; file to find the chart and the version used. For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;v2&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;discourse&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;1.0.0&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;dependencies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;discourse&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;12.6.2&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;repository&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;https://charts.bitnami.com/bitnami&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can pull a local copy of the chart with:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;If the chart is using an &lt;code&gt;oci&lt;/code&gt; url:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;helm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pull&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;oci://registry-1.docker.io/bitnamicharts/postgresql&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--version&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8&lt;/span&gt;.10.X&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--untar&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;postgres8
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;If it&#39;s using an &lt;code&gt;https&lt;/code&gt; url:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;helm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pull&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cost-analyzer&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--repo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://kubecost.github.io/cost-analyzer/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--version&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;.7.2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;And inspect the &lt;code&gt;values.yaml&lt;/code&gt; file and all the templates until you find which key value you need to add.&lt;/p&gt; &lt;p&gt;feat(docker#Cannot invoke &#34;jdk.internal.platform.CgroupInfo.getMountPoint()&#34; because &#34;anyController&#34; is null) : Cannot invoke &#34;jdk.internal.platform.CgroupInfo.getMountPoint()&#34; because &#34;anyController&#34; is null&lt;/p&gt; &lt;p&gt;It&#39;s caused because the docker is not able to access the cgroups, this can be caused by a docker using the legacy cgroups v1 while the linux kernel (&amp;gt;6.12) is using the v2.&lt;/p&gt; &lt;p&gt;The best way to fix it is to upgrade the docker to use v2, if you can&#39;t you need to force the system to use the v1. To do that:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Edit &lt;code&gt;/etc/default/grub&lt;/code&gt; to add the configuration &lt;code&gt;GRUB_CMDLINE_LINUX=&#34;systemd.unified_cgroup_hierarchy=0&#34;&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Then update GRUB: &lt;code&gt;sudo update-grub&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Reboot&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#clone-al-git-repositories-of-a-series-of-organisations&#34;&gt;Clone al git repositories of a series of organisations.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It assumes you have &lt;code&gt;tea&lt;/code&gt; configured to interact with the desired gitea instance.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-e

&lt;span class=&#34;nv&#34;&gt;ORGANIZATIONS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;ansible-playbooks&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;ansible-roles&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;

clone_org_repos&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;has_more&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$has_more&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Fetching page &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$page&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;...&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;csv_output
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;csv_output&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;tea&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;repo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ls&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--output&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;csv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--page&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$page&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-z&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$csv_output&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$csv_output&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&#34;owner&#34;,&#34;name&#34;,&#34;type&#34;,&#34;ssh&#34;&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$csv_output&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-lt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;No more repositories found on page &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$page&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;has_more&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;repo_count&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;IFS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;,&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;owner&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ssh_url&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$owner&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&#34;owner&#34;&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;owner&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$owner&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sed&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;s/&#34;//g&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sed&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;s/&#34;//g&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ssh_url&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ssh_url&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sed&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;s/&#34;//g&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# echo &#34;owner: $owner name: $name ssh_url: $ssh_url&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ssh_url&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ORGANIZATIONS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[*]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;~&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$owner&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Cloning repository: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;!&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;clone&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ssh_url&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$owner&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed to clone &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;, skipping...&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Repository &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; already exists, skipping...&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;repo_count&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;repo_count&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$csv_output&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;((&lt;/span&gt;page++&lt;span class=&#34;o&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;..
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Finished processing &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$org&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

main&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Starting repository cloning process...&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Target organizations: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ORGANIZATIONS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[*]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;!&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tea&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Error: &#39;tea&#39; command not found. Please install gitea tea CLI.&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;!&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Error: &#39;git&#39; command not found. Please install git.&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;org&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ORGANIZATIONS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;!&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$org&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;mkdir&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$org&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;clone_org_repos
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Repository cloning process completed!&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Check the following directories:&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;org&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ORGANIZATIONS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$org&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;  - &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$org&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/ (&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;find&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$org&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-maxdepth&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-type&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; repositories)&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

main&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$@&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;file-management-configuration&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_plugin_development/&#34;&gt;File management configuration&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce radicle.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;radicle.xyz&#34;&gt;Radicle&lt;/a&gt; is an open source, peer-to-peer code collaboration stack built on Git. Unlike centralized code hosting platforms, there is no single entity controlling the network. Repositories are replicated across peers in a decentralized manner, and users are in full control of their data and workflow.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt; - &lt;a href=&#34;radicle.xyz&#34;&gt;Home&lt;/a&gt; - &lt;a href=&#34;radicle.zulipchat.com&#34;&gt;Support&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Sum up the notes of the vim plugin development tutorial.&lt;/p&gt; &lt;p&gt;For the repository name, plugins usually finish with the &lt;code&gt;.nvim&lt;/code&gt; extension. I&#39;m going to call mine &lt;code&gt;org-misc.nvim&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Let&#39;s go with the second, add to your &lt;code&gt;init.lua&lt;/code&gt; the next code:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Hello from our plugin&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=VGid4aN25iI&#34;&gt;How to load our extension&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;We can have the code of our extension wherever we want in our filesystem, but we need to tell Neovim where our plugin’s code is, so it can load the files correctly. Since I use lazy.nvim this is the way to load a plugin from a local folder:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;~/projects/org-misc&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- Your path&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Now if you restart your neovim you won&#39;t see anything until you load it with &lt;code&gt;:lua require &#34;org-misc&#34;&lt;/code&gt; you&#39;ll see the message &lt;code&gt;Hello from our plugin&lt;/code&gt; in the command line.&lt;/p&gt; &lt;p&gt;To automatically load the plugin when you open nvim, use the next lazy config:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;~/projects/org-misc&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- Your path&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;org-misc&#34;&lt;/span&gt;
  &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=VGid4aN25iI&#34;&gt;The plugin file structure&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Usually &lt;code&gt;init.lua&lt;/code&gt; starts with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;M&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;M&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;-- nothing yet&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;M&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where: - &lt;code&gt;M&lt;/code&gt; stands for module, and we&#39;ll start adding it methods. - &lt;code&gt;M.setup&lt;/code&gt; will be the method we use to configure the plugin.&lt;/p&gt; &lt;p&gt;Let&#39;s start with a basic functionality to print some slides:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;M&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;M&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;-- nothing yet&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;---@class present.Slides&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;---@fields slides string[]: The slides of the file&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;--- Takes some lines and parses them&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;--- @param lines string&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;--- @return present.Slides&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse_slides&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lines&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;slides&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;slides&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
    &lt;span class=&#34;kr&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;line&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;ipairs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lines&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;do&lt;/span&gt;
        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;line&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
    &lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;slides&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parse_slides&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;# Hello&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;this is something else&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;# world&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;this is something else&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}))&lt;/span&gt;

&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;M&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You &lt;a href=&#34;https://vi.stackexchange.com/questions/44902/how-can-i-execute-lua-code-from-a-buffer&#34;&gt;can run the code in the current buffer&lt;/a&gt; with &lt;code&gt;:%lua&lt;/code&gt;. For quick access, I&#39;ve defined the next binding:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;leader&amp;gt;X&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;:%lua&amp;lt;cr&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Run the lua code in the current buffer&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The &lt;code&gt;print(parse_slides..&lt;/code&gt; part it&#39;s temporal code so that you can debug your code easily. Once it&#39;s ready you&#39;ll remove them&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Call a method of a module&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To run the method of a module:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;M&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;M&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;-- nothing yet&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;M&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can do &lt;code&gt;require(&#39;org-misc&#39;).setup()&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Set keymaps&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Inside the code of the plugin&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can set keymaps into your plugins by using:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;-- code&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The problem is that it will override the &lt;code&gt;n&lt;/code&gt; key everywhere which is not a good idea, that&#39;s why we normally limit it to the current buffer.&lt;/p&gt; &lt;p&gt;You can get the current buffer with &lt;code&gt;buffer = true&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;-- code&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Continue till the end&lt;/strong&gt; If you want to stop capturing the traffic flow and go to the end ignoring all breakpoints, remove all breakpoints and do &lt;code&gt;.c&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.reddit.com/r/neovim/comments/170jkzh/how_to_reload_plugin_when_developing_them/&#34;&gt;Reload the plugin without exiting nvim&lt;/a&gt;&lt;/strong&gt; If you are using lazy.nvim, there is a feature that lazy.nvim provides for this purpose:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;Lazy&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;reload&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;your_plugin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;your_plugin2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Neovim plugin testing&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;We&#39;re going to test it with &lt;code&gt;plenary&lt;/code&gt;. We&#39;ll add a &lt;code&gt;tests&lt;/code&gt; directory at the root of our repository.&lt;/p&gt; &lt;p&gt;Each of the test files need to end in &lt;code&gt;_spec.lua&lt;/code&gt;, so if we want to test a &lt;code&gt;parse_lines&lt;/code&gt; it will be called &lt;code&gt;parse_lines_spec.lua&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Each test file has the following structure&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;clockin&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;org-misc&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;clockin&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;describe&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;org-misc.clockin&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;it&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;should do clockin&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;assert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;clock_in&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
    &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; These are all the tests for the &lt;code&gt;clockin&lt;/code&gt; method,&lt;/p&gt; &lt;p&gt;Now you can run the test with &lt;code&gt;:PlenaryBustedFile %&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Configuring neotest to run the tests&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Using &lt;code&gt;:PlenaryBustedFile %&lt;/code&gt; is not comfortable, that&#39;s why we&#39;re going to use &lt;a href=&#34;https://github.com/nvim-neotest/neotest?tab=readme-ov-file&#34;&gt;&lt;code&gt;neotest&lt;/code&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Configure it with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;nvim-neotest/neotest&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;dependencies&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;nvim-neotest/neotest-plenary&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
      &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;neotest&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;adapters&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;neotest-plenary&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
    &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Now you can do:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;&amp;lt;leader&amp;gt;tT&lt;/code&gt; to run all test files&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;leader&amp;gt;tt&lt;/code&gt; to run the whole file&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;leader&amp;gt;tl&lt;/code&gt; to run the last test&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;leader&amp;gt;to&lt;/code&gt; to show the output&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;leader&amp;gt;tr&lt;/code&gt; to run the nearest&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;leader&amp;gt;ts&lt;/code&gt; to show the summary&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.reddit.com/r/neovim/comments/18pe4f4/plenarynvim_undefined_global_describe_it_etc_not/&#34;&gt;Remove the Undefined global describe linter warnings&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Add to the root of your repository a &lt;code&gt;.luarc.json&lt;/code&gt; file with &lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/blob/master/.luarc.json&#34;&gt;the next contents&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;$schema&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;diagnostics&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;globals&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;vim&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;hint&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;enable&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;runtime&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;path&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;?.lua&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;?/init.lua&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;pathStrict&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;version&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;LuaJIT&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;telemetry&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;enable&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;workspace&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;checkThirdParty&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Disable&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;ignoreDir&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;.git&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;library&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;./lua&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;$VIMRUNTIME/lua&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;${3rd}/luv/library&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;./tests/.deps/plugins/plenary&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Testing internal functions&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you have a function &lt;code&gt;parse_lines&lt;/code&gt; in your module that you want to test, you can export it as an internal method&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse_lines&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;-- code&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;M&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_parse_lines&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse_lines&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_plugin_development/#control-an-existing-nvim-instance&#34;&gt;Control an existing nvim instance with dap.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Once you have all set up and assuming you&#39;re using the lazyvim keybindings for &lt;code&gt;nvim-dap&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;ds&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[:lua require&#34;osv&#34;.launch({port = 8086})&amp;lt;CR&amp;gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;dq&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[:lua require&#34;osv&#34;.stop()&amp;lt;CR&amp;gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You will debug the plugin by:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Launch the server in the nvim instance where you&#39;re going to run the actions using &lt;code&gt;&amp;lt;leader&amp;gt;ds&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;Open another Neovim instance with the source file (the debugger).&lt;/li&gt; &lt;li&gt;Place breakpoint with &lt;code&gt;&amp;lt;leader&amp;gt;db&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;On the debugger connect to the DAP client with &lt;code&gt;&amp;lt;leader&amp;gt;dc&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;Optionally open the &lt;code&gt;nvim-dap-ui&lt;/code&gt; with &lt;code&gt;&amp;lt;leader&amp;gt;B&lt;/code&gt; in the debugger.&lt;/li&gt; &lt;li&gt;Run your script/plugin in the debuggee&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Now you can interact with the debugger in the window below the code. You have the next commands:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;help&lt;/code&gt;: Show all commands&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;enter&amp;gt;&lt;/code&gt;: run the same action as the previous one. For example if you do &lt;code&gt;.n&lt;/code&gt; and then &lt;code&gt;&amp;lt;enter&amp;gt;&lt;/code&gt; it will run &lt;code&gt;.n&lt;/code&gt; again.&lt;/li&gt; &lt;li&gt;&lt;code&gt;.n&lt;/code&gt; or &lt;code&gt;.next&lt;/code&gt;: next step&lt;/li&gt; &lt;li&gt;&lt;code&gt;.b&lt;/code&gt; or &lt;code&gt;.back&lt;/code&gt;: previous step (if the debugger supports it)&lt;/li&gt; &lt;li&gt;&lt;code&gt;.c&lt;/code&gt; or &lt;code&gt;.continue&lt;/code&gt;: Continue to the next breakpoint.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/fzf_nvim/#how-to-exclude-some-files-from-the-search&#34;&gt;How to exclude some files from the search.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If anyone else comes here in the future and have the following setup&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Using &lt;code&gt;fd&lt;/code&gt; as default command: &lt;code&gt;export FZF_DEFAULT_COMMAND=&#39;fd --type file --hidden --follow&#39;&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Using &lt;code&gt;:Rg&lt;/code&gt; to grep in files&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;And want to exclude a specific path in a git project say &lt;code&gt;path/to/exclude&lt;/code&gt; (but that should not be included in &lt;code&gt;.gitignore&lt;/code&gt;) from both &lt;code&gt;fd&lt;/code&gt; and &lt;code&gt;rg&lt;/code&gt; as used by &lt;code&gt;fzf.vim&lt;/code&gt;, then the easiest way I found to solve to create ignore files for the respective tool then ignore this file in the local git clone (as they are only used by me)&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;git_proj/
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;path/to/exclude&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.rgignore
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;path/to/exclude&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.fdignore
&lt;span class=&#34;nb&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;.rgignore\n.fdignore&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.git/info/exclude
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;plugin-system&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/python_plugin_system/&#34;&gt;Plugin System&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;Correction: Write python plugins with entrypoints.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;python-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/&#34;&gt;Python Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#convert-a-datetime-into-a-date&#34;&gt;Convert a datetime into a date.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;date&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#download-book-previews-from-google-books&#34;&gt;Download book previews from google books.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You will only get some of the pages but it can help in the ending pdf&lt;/p&gt; &lt;p&gt;This first script gets the images data:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;asyncio&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;json&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;re&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;urllib.parse&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;urlparse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse_qs&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;playwright.async_api&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;async_playwright&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;aiohttp&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;aiofiles&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;download_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;session&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;output_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Download image from URL and save to specified path&#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
       &lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&#34;User-Agent&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Mozilla/5.0 (Windows NT 10.0; rv:128.0) Gecko/20100101 Firefox/128.0&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&#34;Accept&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;*/*&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&#34;Accept-Language&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;en-US,en;q=0.5&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&#34;Referer&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;https://books.google.es/&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&#34;DNT&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;1&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&#34;Sec-GPC&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;1&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&#34;Connection&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;keep-alive&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

        &lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;session&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;raise_for_status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;aiofiles&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;output_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;wb&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;

        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Downloaded: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;output_path&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;Exception&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Error downloading &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;extract_page_number&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Extract numeric page number from page ID&#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;match&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;re&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;search&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;PA(\d+)&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;match&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;match&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pid&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;replace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;PA&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;replace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;PP&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;9999&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;# Create output directory&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;output_dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;book_images&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;makedirs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;output_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exist_ok&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;# Keep track of all pages found&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;seen_pids&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;page_counter&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;download_tasks&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;# Create HTTP session for downloads&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;aiohttp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ClientSession&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;session&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;async_playwright&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;browser&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;firefox&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;launch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headless&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;browser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new_context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;user_agent&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Mozilla/5.0 (Windows NT 10.0; rv:128.0) Gecko/20100101 Firefox/128.0&#34;&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

            &lt;span class=&#34;c1&#34;&gt;# Create a page and set up response handling&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;page&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new_page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

            &lt;span class=&#34;c1&#34;&gt;# Store seen URLs to avoid duplicates&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;seen_urls&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

            &lt;span class=&#34;c1&#34;&gt;# Set up response handling for JSON data&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;handle_response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;nonlocal&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;page_counter&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;url&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;url&lt;/span&gt;

                &lt;span class=&#34;c1&#34;&gt;# Only process URLs with jscmd=click3&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;jscmd=click3&#34;&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;url&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;url&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;seen_urls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                        &lt;span class=&#34;c1&#34;&gt;# Try to parse as JSON&lt;/span&gt;
                        &lt;span class=&#34;n&#34;&gt;json_data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
                        &lt;span class=&#34;n&#34;&gt;seen_urls&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

                       &lt;span class=&#34;c1&#34;&gt;# Process and download page data immediately&lt;/span&gt;
                        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;page&#34;&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;json_data&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;json_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;page&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
                            &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;page_data&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;json_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;page&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
                                &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;src&#34;&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;page_data&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;pid&#34;&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;page_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                                    &lt;span class=&#34;n&#34;&gt;pid&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;page_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;pid&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
                                    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pid&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;seen_pids&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                                        &lt;span class=&#34;n&#34;&gt;seen_pids&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                                       &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;page_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;src&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;

                                        &lt;span class=&#34;c1&#34;&gt;# Create filename with sequential numbering&lt;/span&gt;
                                        &lt;span class=&#34;n&#34;&gt;formatted_index&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                                            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pid&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;replace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;PA&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;03d&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
                                        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                                        &lt;span class=&#34;n&#34;&gt;output_file&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;join&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                                            &lt;span class=&#34;n&#34;&gt;output_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;page-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;formatted_index&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;.png&#34;&lt;/span&gt;
                                        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                                        &lt;span class=&#34;n&#34;&gt;page_counter&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;

                                        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                                            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Found new page: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pid&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;, scheduling download&#34;&lt;/span&gt;
                                        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

                                        &lt;span class=&#34;c1&#34;&gt;# Start download immediately&lt;/span&gt;
                                        &lt;span class=&#34;n&#34;&gt;task&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;create_task&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                                            &lt;span class=&#34;n&#34;&gt;download_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;session&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;output_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                                        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                                        &lt;span class=&#34;n&#34;&gt;download_tasks&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;task&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

                        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seen_pids&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                   &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;Exception&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Error processing response from &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

            &lt;span class=&#34;c1&#34;&gt;# Register response handler&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;response&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;handle_response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

            &lt;span class=&#34;c1&#34;&gt;# Navigate to the starting URL&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;book_url&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                &lt;span class=&#34;s2&#34;&gt;&#34;https://books.google.es/books?id=412loEMJA9sC&amp;amp;lpg=PP1&amp;amp;hl=es&amp;amp;pg=PA5&#34;&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;goto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;book_url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

            &lt;span class=&#34;c1&#34;&gt;# Wait for initial page load&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wait_for_load_state&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;networkidle&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

            &lt;span class=&#34;c1&#34;&gt;# Scroll loop variables&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;max_scroll_attempts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;500&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# Safety limit&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;scroll_count&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;pages_before_scroll&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;consecutive_no_new_pages&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;

            &lt;span class=&#34;c1&#34;&gt;# Continue scrolling until we find no new pages for several consecutive attempts&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;scroll_count&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;max_scroll_attempts&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;consecutive_no_new_pages&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                &lt;span class=&#34;c1&#34;&gt;# Get current page count before scrolling&lt;/span&gt;
               &lt;span class=&#34;n&#34;&gt;pages_before_scroll&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seen_pids&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

                &lt;span class=&#34;c1&#34;&gt;# Use PageDown key to scroll&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keyboard&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;press&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;PageDown&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;scroll_count&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;

                &lt;span class=&#34;c1&#34;&gt;# Wait for network activity&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sleep&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

                &lt;span class=&#34;c1&#34;&gt;# Check if we found new pages after scrolling&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seen_pids&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pages_before_scroll&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                    &lt;span class=&#34;n&#34;&gt;consecutive_no_new_pages&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
                    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                        &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Scroll &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;scroll_count&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: Found &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seen_pids&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pages_before_scroll&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; new pages&#34;&lt;/span&gt;
                    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                    &lt;span class=&#34;n&#34;&gt;consecutive_no_new_pages&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
                    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                       &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Scroll &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;scroll_count&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: No new pages found (&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;consecutive_no_new_pages&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/5)&#34;&lt;/span&gt;
                    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Scrolling complete. Found &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seen_pids&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; pages total.&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;browser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

        &lt;span class=&#34;c1&#34;&gt;# Wait for any remaining downloads to complete&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;download_tasks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Waiting for &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;download_tasks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; downloads to complete...&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gather&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;download_tasks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Download complete! Downloaded &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;page_counter&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; images.&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;__main__&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#send-keystrokes-to-an-active-window&#34;&gt;Send keystrokes to an active window.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;subprocess&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;xdotool&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;type&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;Hello world!&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;xdotool&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;key&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;Return&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# press enter&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;xdotool&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;key&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;ctrl+c&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;window_id&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;check_output&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;xdotool&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;getactivewindow&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;decode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;strip&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;xdotool&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;windowactivate&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;window_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#make-temporal-file&#34;&gt;Make temporal file.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;tempfile&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tempfile&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NamedTemporaryFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;suffix&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;.tmp&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;w+&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;encoding&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;utf-8&#34;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;temp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;temp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;# Enter commit message body. Lines starting with &#39;#&#39; will be ignored.&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;temp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;# Leave file empty to skip the body.&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;temp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;flush&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;call&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;editor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;temp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;temp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seek&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;lines&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;temp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;readlines&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#remove-a-directory-with-content&#34;&gt;Remove a directory with content.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;shutil&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;shutil&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rmtree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;/path/to/directory&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#recursively-find-files&#34;&gt;Recursively find files if you only want the files and directories of the first level.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pathlib&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;/your/directory&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;item&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iterdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;File: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;elif&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Directory: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;feat(helm#Download a chart): Download a chart&lt;/p&gt; &lt;p&gt;If the chart is using an &lt;code&gt;oci&lt;/code&gt; url: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;helm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pull&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;oci://registry-1.docker.io/bitnamicharts/postgresql&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--version&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8&lt;/span&gt;.10.X&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--untar&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;postgres8
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;If it&#39;s using an &lt;code&gt;https&lt;/code&gt; url:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;helm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pull&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cost-analyzer&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--repo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://kubecost.github.io/cost-analyzer/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--version&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;.7.2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-value-of-enum-by-value&#34;&gt;Get value of enum by value.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;enum&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Enum&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Enum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;RED&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;GREEN&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;BLUE&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Sometimes it’s useful to access members in enumerations programmatically (i.e. situations where Color.RED won’t do because the exact color is not known at program-writing time). Enum allows such access:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RED&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BLUE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you want to access enum members by name, use item access:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;RED&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RED&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;GREEN&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GREEN&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;```&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-the-directory-of-a-python-script&#34;&gt;Get the directory of a python script.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This can be useful to create relative paths between the script parts in a way that you can still run the script from another directory.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pathlib&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;script_dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;vm&#34;&gt;__file__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parent&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;script_path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;script_dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;../another-file&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;gitpython&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/gitpython/&#34;&gt;GitPython&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/gitpython/#checking-out-an-existing-branch&#34;&gt;Checking out an existing branch.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;heads&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;repo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;heads&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;develop&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;heads&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;develop&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;repo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;head&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;reference&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;develop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pandas&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pandas/&#34;&gt;Pandas&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Try FireDuck!.&lt;/p&gt; &lt;p&gt;NOTE: you might as well use &lt;a href=&#34;https://fireducks-dev.github.io/&#34;&gt;FireDucks&lt;/a&gt; as it has the same API interface and is &lt;a href=&#34;https://fireducks-dev.github.io/docs/benchmarks/&#34;&gt;waaay faster&lt;/a&gt;. The good thing is that you only need to add to the top of your code &lt;code&gt;import fireducks.pandas as pd&lt;/code&gt; and everything should work (I haven&#39;t tried myself).&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;elasticsearch&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/elasticsearch/&#34;&gt;Elasticsearch&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/elasticsearch/#delete-documents-from-all-indices-in-an-elasticsearch-cluster&#34;&gt;Delete documents from all indices in an elasticsearch cluster.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;ES_HOST&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;:-&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;://localhost:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;9200&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;DEFAULT_SETTING&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;5&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Target default value (5%)&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;INDICES&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-XGET&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ES_HOST&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/_cat/indices?h=index&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;INDEX&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$INDICES&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Processing index: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$INDEX&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Close the index to modify static settings&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-XPOST&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ES_HOST&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$INDEX&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/_close&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/null

&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Update expunge_deletes_allowed to 1%&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-XPUT&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ES_HOST&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$INDEX&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/_settings&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-H&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Content-Type: application/json&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;    &#34;index.merge.policy.expunge_deletes_allowed&#34;: &#34;0&#34;&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;  }&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/null

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Reopen the index&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-XPOST&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ES_HOST&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$INDEX&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/_open&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/null

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Trigger forcemerge (async)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# curl -s -XPOST &#34;$ES_HOST/$INDEX/_forcemerge?only_expunge_deletes=true&amp;amp;wait_for_completion=false&#34; &amp;gt; /dev/null&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Forcemerge triggered for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$INDEX&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-XPOST&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ES_HOST&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$INDEX&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/_forcemerge?only_expunge_deletes=true&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Waiting until all forcemerge tasks are done&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ES_HOST&lt;/span&gt;/_cat/tasks&lt;span class=&#34;se&#34;&gt;\?&lt;/span&gt;v&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;forcemerge&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ES_HOST&lt;/span&gt;/_cat/indices&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$INDEX&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;sleep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Close the index again&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-XPOST&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ES_HOST&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$INDEX&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/_close&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/null

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Update to the new default (5%)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-XPUT&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ES_HOST&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$INDEX&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/_settings&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-H&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Content-Type: application/json&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;  {&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;    &#34;index.merge.policy.expunge_deletes_allowed&#34;: &#34;&#39;&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$DEFAULT_SETTING&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&#34;&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;  }&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/null

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Reopen the index&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-XPOST&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ES_HOST&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$INDEX&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/_open&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/null
&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Done! All indices updated.&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;streamlit&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/streamlit/&#34;&gt;Streamlit&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/streamlit/#show-a-spinner-while-the-data-is-loading&#34;&gt;Show a spinner while the data is loading.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;st&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Title&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;st&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;spinner&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Loading data...&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;long_process&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;st&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;markdown&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;content shown once the data is loaded&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/streamlit/#deploy&#34;&gt;Deploy in docker.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Here&#39;s an example &lt;code&gt;Dockerfile&lt;/code&gt; that you can add to the root of your directory&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;python:3.11-slim&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;WORKDIR&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/app&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-y&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;build-essential&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;software-properties-common&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-rf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/apt/lists/*

&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.

&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pip3&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;requirements.txt

&lt;span class=&#34;k&#34;&gt;EXPOSE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;8501&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;HEALTHCHECK&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;CMD&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--fail&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;http://localhost:8501/_stcore/health

&lt;span class=&#34;k&#34;&gt;ENTRYPOINT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;streamlit&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;run&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;app.py&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;--server.port=8501&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;--server.address=0.0.0.0&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;While you debug you may want to replace the &lt;code&gt;COPY . .&lt;/code&gt; to:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;requirements.txt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.

&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pip3&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;requirements.txt

&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;app.py&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;So that the build iterations are faster.&lt;/p&gt; &lt;p&gt;You can build it with &lt;code&gt;docker build -t streamlit .&lt;/code&gt;, then test it with &lt;code&gt;docker run -p 8501:8501 streamlit&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Once you know it&#39;s working you can create a docker compose&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;streamlit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;hm2025_nodos&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;container_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;my_app&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;env_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;.env&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ports&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;8501:8501&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;w w-Error&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;healthcheck&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;test&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;CMD&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;curl&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;--fail&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;http://localhost:8501/_stcore/health&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;30s&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;10s&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;retries&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you use &lt;a href=&#34;&#34;&gt;swag&lt;/a&gt; from linuxserver you can expose the service with the next nginx configuration:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;server&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kn&#34;&gt;listen&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;443&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;ssl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kn&#34;&gt;listen&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;[::]:443&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;ssl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kn&#34;&gt;server_name&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;my_app.*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kn&#34;&gt;include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/config/nginx/ssl.conf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kn&#34;&gt;client_max_body_size&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kn&#34;&gt;location&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# enable the next two lines for http auth&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;#auth_basic &#34;Restricted&#34;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;#auth_basic_user_file /config/nginx/.htpasswd;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# enable the next two lines for ldap auth&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;#auth_request /auth;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;#error_page 401 =200 /login;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kn&#34;&gt;include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/config/nginx/proxy.conf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kn&#34;&gt;resolver&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;127&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;.0.0.11&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;valid=30s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kn&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$upstream_streamlit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;my_container_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kn&#34;&gt;proxy_pass&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;http://&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$upstream_streamlit:8501&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;And if you save your &lt;code&gt;docker-compose.yaml&lt;/code&gt; file into &lt;code&gt;/srv/streamlit&lt;/code&gt; you can use the following systemd service to automatically start it on boot.&lt;/p&gt; &lt;p&gt;``ini [Unit] Description=my_app Requires=docker.service After=docker.service&lt;/p&gt; &lt;p&gt;[Service] Restart=always User=root Group=docker WorkingDirectory=/srv/streamlit TimeoutStartSec=100 RestartSec=2s ExecStart=/usr/bin/docker compose -f docker-compose.yaml up ExecStop=/usr/bin/docker compose -f docker-compose.yaml down&lt;/p&gt; &lt;p&gt;[Install] WantedBy=multi-user.target ```&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;devsecops&#34;&gt;DevSecOps&lt;/h3&gt; &lt;h4 id=&#34;velero&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/argocd/&#34;&gt;Velero&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/argocd/#difference-between-sync-and-refresh&#34;&gt;Difference between sync and refresh.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Sync: Reconciles the current cluster state with the target state in git.&lt;/li&gt; &lt;li&gt;Refresh: Fetches the latest manifests from git and compares the diff with the live state.&lt;/li&gt; &lt;li&gt;Hard Refresh: Clears any caches and does a refresh.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;For more information read &lt;a href=&#34;https://argo-cd.readthedocs.io/en/stable/core_concepts/&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;https://github.com/argoproj/argo-cd/discussions/8260&#34;&gt;2&lt;/a&gt;, &lt;a href=&#34;https://github.com/argoproj/argo-cd/discussions/12237&#34;&gt;3&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add api and library docs.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://docs.goauthentik.io/docs/developer-docs/api/&#34;&gt;Using the API&lt;/a&gt;&lt;/p&gt; &lt;p&gt;There is a &lt;a href=&#34;https://pypi.org/project/authentik-client/&#34;&gt;python library&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/argocd/#argocd-commandline-installation&#34;&gt;ArgoCD commandline installation.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-sSL&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;argocd-linux-amd64&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-m&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;555&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;argocd-linux-amd64&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;~/.local/bin/argocd
rm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;argocd-linux-amd64
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/argocd/#argocd-commandline-usage&#34;&gt;ArgoCD commandline usage.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://codefresh.io/learn/argo-cd/argo-cd-cli-commands-and-best-practices/&#34;&gt;Login into the server&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The &lt;code&gt;argocd login&lt;/code&gt; command is the first step in interacting with the Argo CD API. This command allows you to authenticate yourself, setting up a secure connection between your terminal and the Argo CD server. You’ll need to provide your server’s URL and your credentials. There are three different ways to login, I found that the &lt;code&gt;--core&lt;/code&gt; is the most useful as it will use your kubernetes credentials.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;argocd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;login&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;your.argocd.url.com&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--core&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;production
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Be careful thought that you can&#39;t set different &lt;code&gt;argocd context&lt;/code&gt; for different clusters using the &lt;code&gt;--core&lt;/code&gt; even though &lt;a href=&#34;https://github.com/argoproj/argo-cd/issues/12883&#34;&gt;you set the &lt;code&gt;--kube-context&lt;/code&gt; flag&lt;/a&gt;. The config file &lt;code&gt;~/.config/argocd/config&lt;/code&gt; shows that it&#39;s using whatever kubernetes context you&#39;re using. So be careful that you&#39;re applying it in the correct one!&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Set an argocd context&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The &lt;code&gt;argocd context&lt;/code&gt; command is used to manage your Argo CD contexts. A context is a configuration that represents a Kubernetes cluster, user, and namespace. You can use this command to switch Argo CD between different contexts, allowing you to manage multiple Kubernetes namespaces and clusters from a single terminal.&lt;/p&gt; &lt;p&gt;You can see the different contexts with &lt;code&gt;argocd context&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Get the list of applications&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;argocd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;app&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Refresh an application&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;argocd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;app&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;app_name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--refresh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Show the diff of an application&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;argocd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;app&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;diff&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;app_name
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Sync an application&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;argocd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;app&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sync&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;app_name
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/argocd/#not-there-yet&#34;&gt;More not there yet features.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Python library: I have found none&lt;/li&gt; &lt;li&gt;Argocd TUI: I have found none that is updated&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes/#optimizing-kubernetes-cluster-node-count:-a-strategic-approach&#34;&gt;Optimizing Kubernetes Cluster Node Count: A Strategic Approach.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Reducing the number of nodes in a Kubernetes cluster is a critical strategy for controlling cloud infrastructure costs without compromising system reliability. Here are key best practices to help organizations right-size their Kubernetes deployments:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;1. Availability Zone Consolidation&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Carefully evaluate the number of availability zones (AZs) used in your cluster. While multi-AZ deployments provide redundancy, using too many zones can: - Increase infrastructure complexity - Raise management overhead - Unnecessarily distribute resources - Increase cost without proportional benefit&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Recommendation&lt;/strong&gt;: Aim for a balanced approach, typically 3 AZs, which provides robust redundancy while allowing more efficient resource consolidation.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;2. Intelligent Node Sizing and Management&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Implement sophisticated node management strategies:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Node Provisioning Optimization&lt;/strong&gt; - Use tools like Karpenter to dynamically manage node sizing - Continuously analyze and adjust node types based on actual workload requirements - Consolidate smaller nodes into fewer, more efficiently sized instances&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Overhead Calculation&lt;/strong&gt; Regularly assess system and Kubernetes overhead: - Calculate total system resource consumption - Identify underutilized resources - Understand the overhead percentage for different node types - Make data-driven decisions about node scaling&lt;/p&gt; &lt;p&gt;&lt;strong&gt;3. Advanced Pod Autoscaling Techniques&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Horizontal Pod Autoscaling (HPA)&lt;/strong&gt; - Implement HPA for workloads with variable load - Automatically adjust pod count based on CPU/memory utilization - Ensure efficient resource distribution across existing nodes&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Vertical Pod Autoscaling (VPA)&lt;/strong&gt; - Use VPA in recommendation mode initially - Carefully evaluate automated resource adjustments - Manually apply recommendations to prevent potential service disruptions&lt;/p&gt; &lt;p&gt;&lt;strong&gt;4. Workload Optimization Strategies&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;High Availability Considerations&lt;/strong&gt; - Ensure critical workloads have robust high availability configurations - Design applications to tolerate node failures gracefully - Implement pod disruption budgets to maintain service reliability&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Resource Right-Sizing&lt;/strong&gt; - Conduct thorough analysis of actual resource utilization - Avoid over-provisioning by matching resource requests to actual usage - Use monitoring tools to gain insights into workload characteristics&lt;/p&gt; &lt;p&gt;&lt;strong&gt;5. Continuous Monitoring and Refinement&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Implement comprehensive monitoring of cluster performance&lt;/li&gt; &lt;li&gt;Regularly review node utilization metrics&lt;/li&gt; &lt;li&gt;Create feedback loops for continuous optimization&lt;/li&gt; &lt;li&gt;Develop scripts or use tools to collect and analyze resource usage data&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/authentik/#upgrading&#34;&gt;Upgrading.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can no longer use the &lt;a href=&#34;https://docs.goauthentik.io/docs/releases/2025.2&#34;&gt;latest tag&lt;/a&gt; as it can lead to unintentional updates and potentially broken setups.&lt;/p&gt; &lt;p&gt;The tag will not be removed, however it will also not be updated past &lt;code&gt;2025.2&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;They strongly recommend the use of a specific version tag for authentik instances&#39; container images like &lt;code&gt;:2025.2&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/helm/helm/#get-the-values-of-a-chart&#34;&gt;Get the values of a chart.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;helm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;show&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;values&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zammad&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--repo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://zammad.github.io/zammad-helm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--version&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;14&lt;/span&gt;.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Timestamp Issues (&#34;entry too far behind&#34;).&lt;/p&gt; &lt;p&gt;The most frequent error shows log entries being rejected because their timestamps are too old.&lt;/p&gt; &lt;p&gt;This suggests either:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Clock synchronization issues between your log sources and Loki&lt;/li&gt; &lt;li&gt;Delayed log shipping/buffering&lt;/li&gt; &lt;li&gt;Replay of old logs&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;To solve this:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Check that your hosts&#39; clocks are sync&lt;/li&gt; &lt;li&gt;Adjust Loki&#39;s ingestion window in your config: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;limits_config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;reject_old_samples&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;reject_old_samples_max_age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;168h&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Increase from default (usually 1h)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;You can also prune the logs. For example in the case of a docker container (named &lt;code&gt;dawarich_app&lt;/code&gt;) you can:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;truncate&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/docker/containers/&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;inspect&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;{{.Id}}&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dawarich_app&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;/&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;inspect&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;{{.Id}}&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dawarich_app&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;-json.log
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/loki/#ingestion-rate-limit-exceeded-for-user&#34;&gt;Ingestion rate limit exceeded for user.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Increase rate limits in Loki config:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;limits_config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;ingestion_rate_mb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Increase from 4MB default&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ingestion_burst_size_mb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;16&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Also check which logs are triggering this rate limit because it may be the case that the amount of logs is too great due to an error.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/argocd/#recursively-pull-a-copy-of-all-helm-charts-used-by-an-argocd-repository&#34;&gt;Recursively pull a copy of all helm charts used by an argocd repository.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Including the dependencies of the dependencies.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;argparse&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;logging&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;subprocess&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;sys&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pathlib&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;typing&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Set&lt;/span&gt;

&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;yaml&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;HelmChartPuller&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__init__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pulled_charts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup_logging&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;setup_logging&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;basicConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INFO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;nb&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;[&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%(asctime)s&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;] &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%(levelname)s&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%(message)s&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;datefmt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;%Y-%m-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%d&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; %H:%M:%S&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getLogger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;parse_chart_yaml&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chart_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Parse Chart.yaml file and return its contents.&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chart_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;r&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;encoding&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;utf-8&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;yaml&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;safe_load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;Exception&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed to parse &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chart_file&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;get_dependencies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chart_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Extract dependencies from chart data.&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chart_data&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;dependencies&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[])&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;is_chart_pulled&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Check if chart has already been pulled.&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;chart_id&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chart_id&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pulled_charts&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;mark_chart_pulled&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Mark chart as pulled to avoid duplicates.&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;chart_id&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pulled_charts&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chart_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;pull_chart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;repository&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Pull a Helm chart using appropriate method (OCI or traditional).&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_chart_pulled&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Chart &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; already pulled, skipping&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;

        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Pulling chart: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; version &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; from &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;repository&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

        &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;repository&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;startswith&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;oci://&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;oci_url&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;repository&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;helm&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;pull&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;oci_url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;--version&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;--untar&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
                    &lt;span class=&#34;s2&#34;&gt;&#34;helm&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                    &lt;span class=&#34;s2&#34;&gt;&#34;pull&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                    &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                    &lt;span class=&#34;s2&#34;&gt;&#34;--repo&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                    &lt;span class=&#34;n&#34;&gt;repository&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                    &lt;span class=&#34;s2&#34;&gt;&#34;--version&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                    &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                    &lt;span class=&#34;s2&#34;&gt;&#34;--untar&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;

            &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;capture_output&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;check&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Successfully pulled chart: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mark_chart_pulled&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;

        &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CalledProcessError&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed to pull chart &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;process_chart_dependencies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chart_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Process dependencies from a Chart.yaml file recursively.&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Processing dependencies from: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chart_file&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

        &lt;span class=&#34;n&#34;&gt;chart_data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parse_chart_yaml&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chart_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chart_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;

        &lt;span class=&#34;n&#34;&gt;dependencies&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_dependencies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chart_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dependencies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;No dependencies found in &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chart_file&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;

        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dep&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dependencies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dep&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
           &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dep&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;version&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;repository&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dep&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;repository&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;all&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;repository&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]):&lt;/span&gt;
                &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;warning&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Incomplete dependency in &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chart_file&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dep&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;

            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pull_chart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;repository&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;pulled_chart_dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pulled_chart_dir&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
                    &lt;span class=&#34;n&#34;&gt;dep_chart_file&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pulled_chart_dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Chart.yaml&#34;&lt;/span&gt;
                    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dep_chart_file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
                        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Found Chart.yaml in pulled dependency: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dep_chart_file&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
                        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;process_chart_dependencies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dep_chart_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;find_chart_files&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;search_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Find all Chart.yaml files in the given directory.&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Searching for Chart.yaml files in: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;search_dir&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;search_dir&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rglob&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Chart.yaml&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;check_dependencies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Check if required dependencies are available.&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;helm&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;version&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;capture_output&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;check&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CalledProcessError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;FileNotFoundError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;helm command not found. Please install Helm.&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

        &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;yaml&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;ImportError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                &lt;span class=&#34;s2&#34;&gt;&#34;PyYAML module not found. Install with: pip install PyYAML&#34;&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;target_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Main execution method.&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;check_dependencies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

        &lt;span class=&#34;n&#34;&gt;target_path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;target_path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Directory &#39;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_dir&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#39; does not exist&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Starting to process Helm charts in: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_path&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Charts will be pulled to current directory: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

        &lt;span class=&#34;n&#34;&gt;chart_files&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;find_chart_files&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chart_files&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;No Chart.yaml files found&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;

        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chart_file&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chart_files&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Found Chart.yaml: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chart_file&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;process_chart_dependencies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chart_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Completed processing. Total unique charts pulled: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pulled_charts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pulled_charts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Pulled charts: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;, &#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;join&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;sorted&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pulled_charts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;argparse&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ArgumentParser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Recursively pull Helm charts and their dependencies from Chart.yaml files&#34;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;directory&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;help&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Directory to search for Chart.yaml files&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parse_args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;puller&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HelmChartPuller&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;puller&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;__main__&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes/#cordon-all-arm64-nodes&#34;&gt;Cordon all arm64 nodes.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;nodes&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;kubernetes.io/arch&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;arm64&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;jsonpath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;{.items[*].metadata.name}&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;xargs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cordon
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes/#search-all-the-container-images-in-use-that-match-a-desired-string&#34;&gt;Search all the container images in use that match a desired string.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-e

log&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;[&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;date&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;+%Y-%m-%d %H:%M:%S&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;] &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$*&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

usage&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Usage: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$0&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Describes all pods in all namespaces and greps for images containing &#39;bitnami&#39;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

check_dependencies&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;!&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;&lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Error: kubectl command not found&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Test kubectl connectivity&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;!&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cluster-info&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;&lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Error: Cannot connect to Kubernetes cluster&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

find_bitnami_images&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Getting all pods from all namespaces...&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Get all pods from all namespaces and describe them&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pods&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--all-namespaces&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wide&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--no-headers&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;namespace&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ready&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;status&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;restarts&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;age&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;node&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;nominated&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;readiness&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Describing pod: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$namespace&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Describe the pod and grep for bitnami images&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;describe&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$namespace&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Look for image lines containing bitnami&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;bitnami_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$description&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;image:&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;bitnami&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$bitnami_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;=========================================&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Pod: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$namespace&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Status: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$status&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Bitnami Images Found:&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$bitnami_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;=========================================&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

main&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$#&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-ne&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;usage
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;check_dependencies

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Starting search for Bitnami images in all pods across all namespaces&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;find_bitnami_images
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Search completed&#34;&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

main&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$@&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes/#force-the-removal-of-a-node-from-the-cluster&#34;&gt;Force the removal of a node from the cluster.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To force the removal of a node from a Kubernetes cluster, you have several options depending on your situation:&lt;/p&gt; &lt;p&gt;To prevent new pods from being scheduled while you prepare:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cordon&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;node-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;1. Graceful Node Removal (Recommended)&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;First, try the standard approach:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;drain&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;node-name&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--ignore-daemonsets&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--delete-emptydir-data

kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;delete&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;node&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;node-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;2. Force Removal When Node is Unresponsive&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If the node is unresponsive or the graceful removal fails:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;drain&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;node-name&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--ignore-daemonsets&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--delete-emptydir-data&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--force&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--grace-period&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;

kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;delete&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;node&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;node-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Immediate Forced Removal&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;For emergency situations where you need immediate removal:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;delete&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;node&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;node-name&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--force&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--grace-period&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Common Drain Options&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;--ignore-daemonsets&lt;/code&gt;: Ignores DaemonSet pods (they&#39;ll be recreated anyway)&lt;/li&gt; &lt;li&gt;&lt;code&gt;--delete-emptydir-data&lt;/code&gt;: Deletes pods using emptyDir volumes&lt;/li&gt; &lt;li&gt;&lt;code&gt;--force&lt;/code&gt;: Forces deletion of pods not managed by controllers&lt;/li&gt; &lt;li&gt;&lt;code&gt;--grace-period=0&lt;/code&gt;: Immediately kills pods without waiting&lt;/li&gt; &lt;li&gt;&lt;code&gt;--timeout=300s&lt;/code&gt;: Sets timeout for the drain operation&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Raise alert when value is empty.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Using vector(0)&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;One way to solve it is to use &lt;a href=&#34;https://github.com/grafana/loki/pull/7023&#34;&gt;the &lt;code&gt;vector(0)&lt;/code&gt;&lt;/a&gt; operator with &lt;a href=&#34;https://stackoverflow.com/questions/76489956/how-to-return-a-zero-vector-in-loki-logql-metric-query-when-grouping-is-used-and&#34;&gt;the operation &lt;code&gt;or on() vector(0)&lt;/code&gt;&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;(count_over_time({filename=&#34;/var/log/mail.log&#34;} |= `Mail is sent` [24h]) or on() vector(0)) &amp;lt; 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Using unless&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you&#39;re doing an aggregation over a label this approach won&#39;t work because it will add a new time series with value 0. In those cases use a broader search that includes other logs and the &lt;code&gt;unless&lt;/code&gt; operator:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;(sum by(hostname) (count_over_time({job=&#34;systemd-journal&#34;} [1h]))
unless
sum by(hostname) (count_over_time({service_name=&#34;watchtower&#34;} [1d]))) &amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This will return a value &amp;gt; 0 for any hostname that has systemd-journal logs but no watchtower logs in the past day, which is perfect for alerting conditions.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/postgres/#upgrade-postgres&#34;&gt;Upgrade postgres.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://docs.goauthentik.io/docs/troubleshooting/postgres/upgrade_docker&#34;&gt;Using dump and import&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Dump your database&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Dump your existing database with a command similar to &lt;code&gt;docker compose exec postgresql pg_dump -U authentik -d authentik -cC &amp;gt; upgrade_backup_12.sql&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Before continuing, ensure the SQL dump file &lt;code&gt;upgrade_backup_12.sql&lt;/code&gt; includes all your database content.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Stop your application stack&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Stop all services with &lt;code&gt;docker compose down&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Backup your existing database&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Move the directory where your data is to a new one: &lt;code&gt;mv /path/to/database /path/to/v12-backup&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Modify your docker-compose.yml file&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Update the PostgreSQL service image from &lt;code&gt;docker.io/library/postgres:12-alpine&lt;/code&gt; to &lt;code&gt;docker.io/library/postgres:17-alpine&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Add &lt;code&gt;network_mode: none&lt;/code&gt; and comment out any &lt;code&gt;network&lt;/code&gt; directive to prevent connections being established to the database during the upgrade.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Recreate the database container&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Pull new images and re-create the PostgreSQL container: &lt;code&gt;docker compose pull &amp;amp;&amp;amp; docker compose up --force-recreate -d postgresql&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Apply your backup to the new database: &lt;code&gt;cat upgrade_backup_12.sql | docker compose exec -T postgresql psql -U authentik&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Remove the network configuration setting &lt;code&gt;network_mode: none&lt;/code&gt; that you added to the Compose file in the previous step.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Bring the service up&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Start again the service with &lt;code&gt;docker compose up&lt;/code&gt; and see that everything is working as expected.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/velero/#debug-a-failed-backup&#34;&gt;Debug a failed backup.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To get the available backups you can use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;velero&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;backups
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Check the ones that have Failed in the name and then see the logs with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;velero&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;backup&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;logs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;backup-1h-20251215113154&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;level=info&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;vector&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/zfs_storage_planning/&#34;&gt;vector&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add the stats of the Enterprise Capacity seagate disk.&lt;/p&gt; &lt;table&gt; &lt;thead&gt; &lt;tr&gt; &lt;th&gt;Specs&lt;/th&gt; &lt;th&gt;IronWolf&lt;/th&gt; &lt;th&gt;IronWolf Pro&lt;/th&gt; &lt;th&gt;Exos 7E8 8TB&lt;/th&gt; &lt;th&gt;Exos 7E10 8TB&lt;/th&gt; &lt;th&gt;Exos X18 16TB&lt;/th&gt; &lt;th&gt;Enterpri. Capacity&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Bays&lt;/td&gt; &lt;td&gt;1-8&lt;/td&gt; &lt;td&gt;1-24&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Capacity&lt;/td&gt; &lt;td&gt;1-12TB&lt;/td&gt; &lt;td&gt;2-20TB&lt;/td&gt; &lt;td&gt;8TB&lt;/td&gt; &lt;td&gt;8TB&lt;/td&gt; &lt;td&gt;16 TB&lt;/td&gt; &lt;td&gt;10 TB&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;RPM&lt;/td&gt; &lt;td&gt;5,400 RPM (3-6TB)&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;RPM&lt;/td&gt; &lt;td&gt;5,900 RPM (1-3TB)&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;RPM&lt;/td&gt; &lt;td&gt;7,200 RPM (8-12TB)&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Speed&lt;/td&gt; &lt;td&gt;180MB/s (1-12TB)&lt;/td&gt; &lt;td&gt;214-260MB/s (4-18TB)&lt;/td&gt; &lt;td&gt;249 MB/s&lt;/td&gt; &lt;td&gt;255 MB/s&lt;/td&gt; &lt;td&gt;258 MB/s&lt;/td&gt; &lt;td&gt;254 MB/s&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Cache&lt;/td&gt; &lt;td&gt;64MB (1-4TB)&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Cache&lt;/td&gt; &lt;td&gt;256MB (3-12TB)&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Power Consumption&lt;/td&gt; &lt;td&gt;10.1 W&lt;/td&gt; &lt;td&gt;10.1 W&lt;/td&gt; &lt;td&gt;12.81 W&lt;/td&gt; &lt;td&gt;11.03 W&lt;/td&gt; &lt;td&gt;9.31 W&lt;/td&gt; &lt;td&gt;8 W&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Power Consumption Rest&lt;/td&gt; &lt;td&gt;7.8 W&lt;/td&gt; &lt;td&gt;7.8 W&lt;/td&gt; &lt;td&gt;7.64 W&lt;/td&gt; &lt;td&gt;7.06 W&lt;/td&gt; &lt;td&gt;5.08 W&lt;/td&gt; &lt;td&gt;4.5 W&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Workload&lt;/td&gt; &lt;td&gt;180TB/yr&lt;/td&gt; &lt;td&gt;300TB/yr&lt;/td&gt; &lt;td&gt;550TB/yr&lt;/td&gt; &lt;td&gt;550TB/yr&lt;/td&gt; &lt;td&gt;550TB/yr&lt;/td&gt; &lt;td&gt;&amp;lt; 550TB/yr&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;MTBF&lt;/td&gt; &lt;td&gt;1 million&lt;/td&gt; &lt;td&gt;1 million&lt;/td&gt; &lt;td&gt;2 millions&lt;/td&gt; &lt;td&gt;2 millions&lt;/td&gt; &lt;td&gt;2.5 millions&lt;/td&gt; &lt;td&gt;2.5 millions&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Noise idle&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;3.0 bels max&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Noise performance seek&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;3.4 bels max&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;diff --git a/mkdocs.yml b/mkdocs.yml index 7d0201801c..ade48234b0 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -5,19 +5,18 @@ site_author: Lyz site_url: &lt;a href=&#34;https://lyz-code.github.io/blue-book&#34;&gt;https://lyz-code.github.io/blue-book&lt;/a&gt; nav: - Introduction: index.md - - Projects: projects.md - Activism: - activism.md - Antifascism: - antifascism.md - Antifascist Actions: antifascist_actions.md - Hacktivism: - - Gatherings: - - hacktivist_gatherings.md - - Chaos Communication Congress: ccc.md - - Collectives: hacktivist_collectives.md - - Tools: - - Mobile Verification Toolkit: mobile_verification_toolkit.md + - Gatherings: + - hacktivist_gatherings.md + - Chaos Communication Congress: ccc.md + - Collectives: hacktivist_collectives.md + - Tools: + - Mobile Verification Toolkit: mobile_verification_toolkit.md - Anti-Colonialism: anticolonialism.md - Anti-Transphobia: antitransphobia.md - Anti-Racism: antiracism.md @@ -27,6 +26,7 @@ nav: - Feminism: - Privileges: feminism/privileges.md - Palestine: palestine.md + - Anarchism: anarchism.md - Memoria histórica: memoria_historica.md - Anti-Tourism: antitourism.md - Mentoring: mentoring.md @@ -36,153 +36,154 @@ nav: - Laboral: laboral.md - Collaborating tools: collaborating_tools.md - Conference organisation: conference_organisation.md - - Ludditest: luddites.md + - Ludditest: luddites.md - Life Management: - life_management.md - Time management: - - time_management.md - - Time management abstraction levels: time_management_abstraction_levels.md - - Action Management: action_management.md - - Roadmap Adjustment: - - roadmap_adjustment.md - - Strategy: strategy.md - - Systems Thinking: systems_thinking.md - - Roadmap Management Tools: - - roadmap_tools.md - - Org Mode: - - orgmode.md - - Org-rw: org_rw.md - - Orgzly: orgzly.md - - OpenProject: openproject.md - - Habit management: habit_management.md - - Interruption management: - - interruption_management.md - - Interruption Management Analysis: - - Work Interruption Analysis: work_interruption_analysis.md - - Personal Interruption Analysis: personal_interruption_analysis.md - - Week management: week_management.md - - Calendar management: - - calendar_management.md - - Calendar automation: - - vdirsyncer: vdirsyncer.md - - Calendar clients: - - Khal: khal.md - - Gancio: gancio.md - - Time management theories: - - Getting Things Done: gtd.md + - time_management.md + - Time management abstraction levels: time_management_abstraction_levels.md + - Action Management: action_management.md + - Roadmap Adjustment: + - roadmap_adjustment.md + - Strategy: strategy.md + - Systems Thinking: systems_thinking.md + - Roadmap Management Tools: + - roadmap_tools.md + - Org Mode: + - orgmode.md + - Org-rw: org_rw.md + - Orgzly: orgzly.md + - OpenProject: openproject.md + - Habit management: habit_management.md + - Interruption management: + - interruption_management.md + - Interruption Management Analysis: + - Work Interruption Analysis: work_interruption_analysis.md + - Personal Interruption Analysis: personal_interruption_analysis.md + - Week management: week_management.md + - Calendar management: + - calendar_management.md + - Calendar automation: + - vdirsyncer: vdirsyncer.md + - Calendar clients: + - Khal: khal.md + - Gancio: gancio.md + - Time management theories: + - Getting Things Done: gtd.md - Life chores management: - - Trip management: - - Route management: route_management.md - - Map management: map_management.md - - Food management: food_management.md - - Stock management: - - Grocy: grocy_management.md - - Money management: - - money_management.md - - beancount: - - beancount.md - - bean-sql: bean_sql.md - - Fava Dashboards: fava_dashboards.md - - Tools management: - - tool_management.md - - Email management: - - email_management.md - - Email automation: - - email_automation.md - - Email automation tools: - - mbsync: mbsync.md - - mirador: mirador.md - - afew: afew.md - - notmuch: notmuch.md - - Email automation libraries: - - mailbox: mailbox.md - - IMAP: - - IMAP library comparison: python_imap.md - - imap-tools: imap_tools.md - - Email clients: - - himalaya: himalaya.md - - alot: alot.md - - Email protocols: - - Maildir: maildir.md - - Instant Messages Management: - - instant_messages_management.md - - XMPP/Jabber: - - Dino: dino.md - - Gajim: gajim.md - - Profanity: profanity.md - - Matrix: - - matrix.md - - Matrix Highlight: matrix_highlight.md - - Rocketchat: rocketchat.md - - Computer configuration management: configuration_management.md + - Trip management: + - Route management: route_management.md + - Map management: map_management.md + - Food management: food_management.md + - Stock management: + - Grocy: grocy_management.md + - Money management: + - money_management.md + - beancount: + - beancount.md + - bean-sql: bean_sql.md + - Fava Dashboards: fava_dashboards.md + - Tools management: + - tool_management.md + - Email management: + - email_management.md + - Email automation: + - email_automation.md + - Email automation tools: + - mbsync: mbsync.md + - mirador: mirador.md + - afew: afew.md + - notmuch: notmuch.md + - Email automation libraries: + - mailbox: mailbox.md + - IMAP: + - IMAP library comparison: python_imap.md + - imap-tools: imap_tools.md + - Email clients: + - himalaya: himalaya.md + - alot: alot.md + - Email protocols: + - Maildir: maildir.md + - Instant Messages Management: + - instant_messages_management.md + - XMPP/Jabber: + - Dino: dino.md + - Gajim: gajim.md + - Profanity: profanity.md + - Matrix: + - matrix.md + - Matrix Highlight: matrix_highlight.md + - Signal: signal.md + - Rocketchat: rocketchat.md + - Computer configuration management: configuration_management.md - Content Management: - - Music Management: - - music_management.md - - MusicBrainz: musicbrainz.md - - Mopidy: mopidy.md - - Beets: beets.md - - Koel: koel.md - - yt-dlp: yt-dlp.md - - Book Management: - - book_management.md - - Bookwyrm: bookwyrm.md - - Movies Management: - - Jellyfin: jellyfin.md - - Ombi: ombi.md - - Mediatracker: mediatracker.md - - ffmpeg: ffmpeg.md - - transcoding: - - transcoding.md - - unmanic: unmanic.md - - Kodi: kodi.md - - News Management: - - news_management.md - - RSS: rss.md - - Wallabag: wallabag.md - - Photo management: - - photo_self_hosted.md - - Immich: immich.md - - Video management: video_management.md - - Videogames management: - - moonlight: moonlight.md - - retroarch: retroarch.md + - Music Management: + - music_management.md + - MusicBrainz: musicbrainz.md + - Mopidy: mopidy.md + - Beets: beets.md + - Koel: koel.md + - yt-dlp: yt-dlp.md + - Book Management: + - book_management.md + - Bookwyrm: bookwyrm.md + - Movies Management: + - Jellyfin: jellyfin.md + - Ombi: ombi.md + - Mediatracker: mediatracker.md + - ffmpeg: ffmpeg.md + - transcoding: + - transcoding.md + - unmanic: unmanic.md + - Kodi: kodi.md + - News Management: + - news_management.md + - RSS: rss.md + - Wallabag: wallabag.md + - Photo management: + - photo_self_hosted.md + - Immich: immich.md + - Video management: video_management.md + - Videogames management: + - moonlight: moonlight.md + - retroarch: retroarch.md - Knowledge Management: - - knowledge_management.md - - Spaced Repetition: - - spaced_repetition.md - - Anki: anki.md - - Mochi: mochi.md - - Analytical web reading: - - analytical_web_reading.md - - Hypothesis: linux/hypothesis.md - - Digital Gardens: - - digital_garden.md - - mkdocs: linux/mkdocs.md - - Build your own Digital Garden: writing/build_your_own_wiki.md - - Forking this garden: forking_this_wiki.md - - Aleph: aleph.md - - Wordpress: wordpress.md - - Relationship Management: - - relationship_management.md - - monica: linux/monica.md + - knowledge_management.md + - Spaced Repetition: + - spaced_repetition.md + - Anki: anki.md + - Mochi: mochi.md + - Analytical web reading: + - analytical_web_reading.md + - Hypothesis: linux/hypothesis.md + - Digital Gardens: + - digital_garden.md + - mkdocs: linux/mkdocs.md + - Build your own Digital Garden: writing/build_your_own_wiki.md + - Forking this garden: forking_this_wiki.md + - Aleph: aleph.md + - Wordpress: wordpress.md + - Relationship Management: + - relationship_management.md + - monica: linux/monica.md - Process Automation: - - process_automation.md - - AI: - - Open WebUI: openwebui.md - - NLP: - - spacy: spacy.md - - Virtual Assistant: virtual_assistant.md - - Monitor web changes: - - Changedetection.io: changedetection.md - - Monitorizar billetes de renfe: renfe.md + - process_automation.md + - AI: + - Open WebUI: openwebui.md + - NLP: + - spacy: spacy.md + - Virtual Assistant: virtual_assistant.md + - Monitor web changes: + - Changedetection.io: changedetection.md + - Monitorizar billetes de renfe: renfe.md - Torrent management: - - torrents.md - - qBittorrent: qbittorrent.md - - Rtorrent: rtorrent.md - - Unpackerr: unpackerr.md - - Life logging: - - life_logging.md - - ActivityWatch: activitywatch.md + - torrents.md + - qBittorrent: qbittorrent.md + - Rtorrent: rtorrent.md + - Unpackerr: unpackerr.md + - Life logging: + - life_logging.md + - ActivityWatch: activitywatch.md - Health: - Sleep: sleep.md - Teeth: @@ -213,7 +214,8 @@ nav: - Create the documentation repository: &amp;gt;- coding/python/python_project_template/python_docs.md - Load config from YAML: coding/python/python_config_yaml.md - - Configure SQLAlchemy to use the MariaDB/Mysql backend: &amp;gt;- + - Configure SQLAlchemy to use the MariaDB/Mysql backend: + &amp;gt;- coding/python/python_project_template/python_sqlalchemy_mariadb.md - Configure Docker to host the application: &amp;gt;- coding/python/python_project_template/python_docker.md @@ -269,9 +271,9 @@ nav: - Python Mysql: python_mysql.md - pythonping: pythonping.md - Python Prometheus: python-prometheus.md - - Python Telegram: - - python-telegram.md - - pytelegrambotapi: pytelegrambotapi.md + - Python Telegram: + - python-telegram.md + - pytelegrambotapi: pytelegrambotapi.md - Python VLC: python_vlc.md - Playwright: playwright.md - Plotly: coding/python/plotly.md @@ -299,13 +301,13 @@ nav: - Code Styling: coding/python/python_code_styling.md - Docstrings: coding/python/docstrings.md - Properties: python_properties.md - - Protocols: python_protocols.md + - Protocols: python_protocols.md - Package Management: - - python_package_management.md - - PDM: pdm.md - - pipx: pipx.md - - Pipenv: pipenv.md - - Poetry: python_poetry.md + - python_package_management.md + - PDM: pdm.md + - pipx: pipx.md + - Pipenv: pipenv.md + - Poetry: python_poetry.md - Lazy loading: lazy_loading.md - Plugin System: python_plugin_system.md - Profiling: python_profiling.md @@ -351,65 +353,66 @@ nav: - JWT: devops/jwt.md - React: coding/react/react.md - Coding tools: - - IDES: - - Vim: - - vim.md - - Vim configuration: - - vim_config.md - - Vim Keymaps: vim_keymaps.md - - Vim Package Manager: - - vim_plugin_managers.md - - LazyVim: lazyvim.md - - Packer: vim_packer.md - - UI management configuration: - - Vim foldings: vim_foldings.md - - Vim movement: vim_movement.md - - Tabs vs Buffers: vim_tabs.md - - File management configuration: - - NeoTree: neotree.md - - Telescope: telescope.md - - Editing specific configuration: - - vim_editor_plugins.md - - Vim formatters: vim_formatters.md - - Vim autocomplete: vim_completion.md - - Vim markdown: vim_markdown.md - - Vim spelling: vim_spelling.md - - Vim autosave: vim_autosave.md - - Coding specific configuration: - - vim_coding_plugins.md - - Treesitter: vim_treesitter.md - - LSP: vim_lsp.md - - Snippets: luasnip.md - - DAP: vim_dap.md - - Git management configuration: - - vim_git.md - - Diffview: diffview.md - - gitsigns: gitsigns.md - - Testing management configuration: vim_testing.md - - Email management: vim_email.md - - Other Vim Plugins: - - linux/vim/vim_plugins.md - - Vim Snippets: vim_snippets.md - - Vim Troubleshooting: vim_troubleshooting.md - - Neovim Plugin Development: vim_plugin_development.md - - Vi vs Vim vs Neovim: vim_vs_neovim.md - - Tridactyl: tridactyl.md - - VSCodium: vscodium.md - - Coding with AI: ai_coding.md - - Git: - - git.md - - Github cli: gh.md - - Forgejo: forgejo.md - - Gitea: gitea.md - - Data orchestrators: - - data_orchestrators.md - - Kestra: kestra.md - - memorious: memorious.md - - Scrapers: - - morph.io: morph_io.md - - ETL: - - Singer: singer.md - - Espanso: espanso.md + - IDES: + - Vim: + - vim.md + - Vim configuration: + - vim_config.md + - Vim Keymaps: vim_keymaps.md + - Vim Package Manager: + - vim_plugin_managers.md + - LazyVim: lazyvim.md + - Packer: vim_packer.md + - UI management configuration: + - Vim foldings: vim_foldings.md + - Vim movement: vim_movement.md + - Tabs vs Buffers: vim_tabs.md + - File management configuration: + - NeoTree: neotree.md + - Telescope: telescope.md + - Editing specific configuration: + - vim_editor_plugins.md + - Vim formatters: vim_formatters.md + - Vim autocomplete: vim_completion.md + - Vim markdown: vim_markdown.md + - Vim spelling: vim_spelling.md + - Vim autosave: vim_autosave.md + - Coding specific configuration: + - vim_coding_plugins.md + - Treesitter: vim_treesitter.md + - LSP: vim_lsp.md + - Snippets: luasnip.md + - DAP: vim_dap.md + - Git management configuration: + - vim_git.md + - Diffview: diffview.md + - gitsigns: gitsigns.md + - Testing management configuration: vim_testing.md + - Email management: vim_email.md + - Other Vim Plugins: + - linux/vim/vim_plugins.md + - Vim Snippets: vim_snippets.md + - Vim Troubleshooting: vim_troubleshooting.md + - Neovim Plugin Development: vim_plugin_development.md + - Vi vs Vim vs Neovim: vim_vs_neovim.md + - Tridactyl: tridactyl.md + - VSCodium: vscodium.md + - Coding with AI: ai_coding.md + - Git: + - git.md + - Github cli: gh.md + - Forgejo: forgejo.md + - Gitea: gitea.md + - Radicle: radicle.md + - Data orchestrators: + - data_orchestrators.md + - Kestra: kestra.md + - memorious: memorious.md + - Scrapers: + - morph.io: morph_io.md + - ETL: + - Singer: singer.md + - Espanso: espanso.md - Generic Coding Practices: - How to code: how_to_code.md - Program Versioning: @@ -435,8 +438,8 @@ nav: - Microservices: architecture/microservices.md - Restful APIS: architecture/restful_apis.md - OCR: - - Table parsing: - - Camelot: camelot.md + - Table parsing: + - Camelot: camelot.md - Frontend Development: frontend_development.md - Park programming: park_programming.md - Sponsor: sponsor.md @@ -453,8 +456,8 @@ nav: - Helmfile: devops/helmfile.md - Terraform: terraform.md - Ansible: - - Ansible Snippets: ansible_snippets.md - - Molecule: molecule.md + - Ansible Snippets: ansible_snippets.md + - Molecule: molecule.md - Nix: nix.md - Dotfiles: - dotfiles.md @@ -517,8 +520,8 @@ nav: - S3: devops/aws/s3.md - WAF: aws_waf.md - Databases: - - Redis: architecture/redis.md - - RabbitMQ: rabbitmq.md + - Redis: architecture/redis.md + - RabbitMQ: rabbitmq.md - Continuous Deployment: - ArgoCD: argocd.md - Continuous Integration: @@ -553,21 +556,21 @@ nav: - renovate: renovate.md - letsencrypt: letsencrypt.md - Threat modeling: - - Privacy threat modeling: privacy_threat_modeling.md + - Privacy threat modeling: privacy_threat_modeling.md - Storage: - - storage.md - - NAS: nas.md - - OpenZFS: - - linux/zfs.md - - OpenZFS storage planning: zfs_storage_planning.md - - Sanoid: sanoid.md - - ZFS Prometheus exporter: zfs_exporter.md - - Hard drive health: hard_drive_health.md - - Resilience: - - linux_resilience.md - - Memtest: memtest.md - - watchdog: watchdog.md - - Magic keys: magic_keys.md + - storage.md + - NAS: nas.md + - OpenZFS: + - linux/zfs.md + - OpenZFS storage planning: zfs_storage_planning.md + - Sanoid: sanoid.md + - ZFS Prometheus exporter: zfs_exporter.md + - Hard drive health: hard_drive_health.md + - Resilience: + - linux_resilience.md + - Memtest: memtest.md + - watchdog: watchdog.md + - Magic keys: magic_keys.md - Monitoring: - Monitoring Comparison: monitoring_comparison.md - Prometheus: @@ -587,21 +590,21 @@ nav: devops/prometheus/prometheus_troubleshooting.md - Grafana: grafana.md - Log analysis: - - Loki: - - loki.md - - Logcli: logcli.md - - Promtail: promtail.md - - Graylog: graylog.md - - Elastic Security: elastic_security.md + - Loki: + - loki.md + - Logcli: logcli.md + - Promtail: promtail.md + - Graylog: graylog.md + - Elastic Security: elastic_security.md - SIEM: siem.md - Databases: - - PostgreSQL: - - postgres.md - - Postgres operators: - - postgres_operators.md - - Zalando Postgres operator: zalando_postgres_operator.md - - elasticsearch: linux/elasticsearch.md - - Oracle Database: oracle_database.md + - PostgreSQL: + - postgres.md + - Postgres operators: + - postgres_operators.md + - Zalando Postgres operator: zalando_postgres_operator.md + - elasticsearch: linux/elasticsearch.md + - Oracle Database: oracle_database.md - Authentication: - Authentik: authentik.md - API Management: @@ -613,11 +616,11 @@ nav: - Refinement Template: refinement_template.md - Hardware: - CPU: cpu.md - - RAM: - - ram.md - - ECC RAM: - - ecc.md - - rasdaemon: rasdaemon.md + - RAM: + - ram.md + - ECC RAM: + - ecc.md + - rasdaemon: rasdaemon.md - Power Supply Unit: psu.md - GPU: gpu.md - Pedal PC: pedal_pc.md @@ -627,52 +630,54 @@ nav: - linux.md - Linux Snippets: linux_snippets.md - Distros: - - Libreelec: libreelec.md - - Tails: tails.md + - Libreelec: libreelec.md + - Tails: tails.md - Recovery tools: - - finnix: finnix.md + - finnix: finnix.md - Security tools: - - fail2ban: linux/fail2ban.md - - pass: pass.md - - Wireshark: wireshark.md + - fail2ban: linux/fail2ban.md + - pass: pass.md + - Wireshark: wireshark.md - Sysadmin tools: - - brew: linux/brew.md - - detox: detox.md - - Docker: docker.md - - Watchtower: watchtower.md - - Dynamic DNS: dynamicdns.md - - goaccess: goaccess.md - - Gotify: gotify.md - - HAProxy: linux/haproxy.md - - journald: journald.md - - LUKS: linux/luks/luks.md - - Outrun: outrun.md - - rm: linux/rm.md - - sed: sed.md - - Syncthing: linux/syncthing.md - - Tahoe-LAFS: tahoe.md - - Wake on Lan: wake_on_lan.md - - Wireguard: linux/wireguard.md - - yq: yq.md - - zip: linux/zip.md + - brew: linux/brew.md + - detox: detox.md + - Docker: docker.md + - Watchtower: watchtower.md + - Dynamic DNS: dynamicdns.md + - goaccess: goaccess.md + - Gotify: gotify.md + - HAProxy: linux/haproxy.md + - journald: journald.md + - LUKS: linux/luks/luks.md + - Outrun: outrun.md + - rm: linux/rm.md + - sed: sed.md + - Syncthing: linux/syncthing.md + - Tahoe-LAFS: tahoe.md + - Wake on Lan: wake_on_lan.md + - Wireguard: linux/wireguard.md + - yq: yq.md + - zip: linux/zip.md - Window manager tools: - - dunst: dunst.md - - ferdium: ferdium.md - - i3wm: i3wm.md - - rofi: rofi.md + - dunst: dunst.md + - ferdium: ferdium.md + - i3wm: i3wm.md + - rofi: rofi.md - User tools: - - Browsers: - - google chrome: linux/google_chrome.md - - Chromium: chromium.md - - Hushboard: husboard.md - - Peek: peek.md - - Terminals: - - terminal_comparison.md - - Alacritty: alacritty.md - - Wezterm: wezterm.md - - Kitty: kitty.md - - Instant messaging apps: - - Delta Chat: deltachat.md + - Browsers: + - google chrome: linux/google_chrome.md + - Chromium: chromium.md + - Hushboard: husboard.md + - Peek: peek.md + - Terminals: + - terminal_comparison.md + - Alacritty: alacritty.md + - Wezterm: wezterm.md + - Kitty: kitty.md + - Instant messaging apps: + - Delta Chat: deltachat.md + - Simplex Chat: simplexchat.md + - Android: - Android Tips: android_tips.md - OS: @@ -687,7 +692,6 @@ nav: - Orgzly: orgzly.md - OsmAnd: osmand.md - Seedvault: seedvault.md - - Signal: signal.md - Android SDK Platform tools: android_sdk.md - Arts: - Writing: @@ -703,8 +707,8 @@ nav: - Dancing: - Rave Dances: dancing/rave_dances.md - Swing: - - Shag: shag.md - - Lindy Hop: lindy.md + - Shag: shag.md + - Lindy Hop: lindy.md - Shuffle: - Basics: dancing/shuffle_basics.md - Kicks: dancing/shuffle_kicks.md @@ -729,7 +733,7 @@ nav: - board_games.md - Regicide: regicide.md - Music: - - Sister Rosetta Tharpe: sister_rosetta_tharpe.md + - Sister Rosetta Tharpe: sister_rosetta_tharpe.md - Sudokus: sudokus.md - Drawing: - drawing/drawing.md @@ -741,23 +745,24 @@ nav: - Emojis: emojis.md - Languages: - Castellano: castellano.md - - Galego: + - Galego: - galego.md - Diccionario galego-castelan: diccionario_galego.md + - Esperanto: esperanto.md - Science: - - Artificial Intelligence: - - ai.md - - Speech to text: - - Whisper: whisper.md - - Speech recognition: speech_recognition.md - - Coding by Voice: coding_by_voice.md - - Data Analysis: + - Artificial Intelligence: + - ai.md + - Speech to text: + - Whisper: whisper.md + - Speech recognition: speech_recognition.md + - Coding by Voice: coding_by_voice.md + - Data Analysis: - data_analysis.md - Recommender Systems: &amp;gt;- data_analysis/recommender_systems/recommender_systems.md - Parsers: parsers.md - CSV exploring: - - csvlens: csvlens.md + - csvlens: csvlens.md - Psychology: - psychology.md - The XY Problem: psychology/the_xy_problem.md @@ -765,6 +770,18 @@ nav: - Botany: - Trees: botany/trees.md - Math: math.md + - Reviews: + - Year reviews: year_reviews.md + - Content reviews: + - Books: books.md + # - Movies: movies.md + # - Music: music.md + # - TV Shows: tv_shows.md + - Podcasts: podcasts.md + # - Videogames: videogames.md + # - Boardgames: boardgames.md + # - Streaming channels: streaming_channels.md + - Projects: projects.md - Contact: contact.md&lt;/p&gt; &lt;p&gt;plugins: @@ -825,7 +842,7 @@ theme:&lt;/p&gt; &lt;p&gt;palette: # Light mode - - media: &#39;(prefers-color-scheme: light)&#39; + - media: &#34;(prefers-color-scheme: light)&#34; scheme: default primary: blue grey accent: light blue @@ -834,7 +851,7 @@ theme: name: Switch to dark mode&lt;/p&gt; &lt;pre&gt;&lt;code&gt; # Dark mode
&lt;/code&gt;&lt;/pre&gt; &lt;ul&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;media: &#39;(prefers-color-scheme: dark)&#39;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;media: &#34;(prefers-color-scheme: dark)&#34; scheme: slate primary: blue grey accent: light blue&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Suggest to look at the slimbook.&lt;/p&gt; &lt;p&gt;I built a server pretty much the same as the &lt;a href=&#34;https://slimbook.com/en/shop/product/nas-cube-1510?category=10&#34;&gt;slimbook&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce smartctl.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Self-Monitoring,_Analysis_and_Reporting_Technology&#34;&gt;Self-Monitoring, Analysis, and Reporting Technology (S.M.A.R.T. or SMART)&lt;/a&gt; is a monitoring system included in computer hard disk drives (HDDs) and solid-state drives (SSDs). Its primary function is to detect and report various indicators of drive reliability, or how long a drive can function while anticipating imminent hardware failures.&lt;/p&gt; &lt;p&gt;When S.M.A.R.T. data indicates a possible imminent drive failure, software running on the host system may notify the user so action can be taken to prevent data loss, and the failing drive can be replaced and no data is lost.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;General information&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Self-Monitoring,_Analysis_and_Reporting_Technology#Accuracy&#34;&gt;Accuracy&lt;/a&gt;&lt;/em&gt;&lt;/p&gt; &lt;p&gt;A field study at Google covering over 100,000 consumer-grade drives from December 2005 to August 2006 found correlations between certain S.M.A.R.T. information and annualized failure rates:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;In the 60 days following the first uncorrectable error on a drive (S.M.A.R.T. attribute 0xC6 or 198) detected as a result of an offline scan, the drive was, on average, 39 times more likely to fail than a similar drive for which no such error occurred.&lt;/li&gt; &lt;li&gt;First errors in reallocations, offline reallocations (S.M.A.R.T. attributes 0xC4 and 0x05 or 196 and 5) and probational counts (S.M.A.R.T. attribute 0xC5 or 197) were also strongly correlated to higher probabilities of failure.&lt;/li&gt; &lt;li&gt;Conversely, little correlation was found for increased temperature and no correlation for usage level. However, the research showed that a large proportion (56%) of the failed drives failed without recording any count in the &#34;four strong S.M.A.R.T. warnings&#34; identified as scan errors, reallocation count, offline reallocation, and probational count.&lt;/li&gt; &lt;li&gt;Further, 36% of failed drives did so without recording any S.M.A.R.T. error at all, except the temperature, meaning that S.M.A.R.T. data alone was of limited usefulness in anticipating failures.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://blog.shadypixel.com/monitoring-hard-drive-health-on-linux-with-smartmontools/&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;On Debian systems:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;smartmontools
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;By default when you install it all your drives are checked periodically with the &lt;code&gt;smartd&lt;/code&gt; daemon under the &lt;code&gt;smartmontools&lt;/code&gt; systemd service.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Running the tests&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Self-Monitoring,_Analysis_and_Reporting_Technology#Self-tests&#34;&gt;Test types&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;S.M.A.R.T. drives may offer a number of self-tests:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Short: Checks the electrical and mechanical performance as well as the read performance of the disk. Electrical tests might include a test of buffer RAM, a read/write circuitry test, or a test of the read/write head elements. Mechanical test includes seeking and servo on data tracks. Scans small parts of the drive&#39;s surface (area is vendor-specific and there is a time limit on the test). Checks the list of pending sectors that may have read errors, and it usually takes under two minutes.&lt;/li&gt; &lt;li&gt;Long/extended: A longer and more thorough version of the short self-test, scanning the entire disk surface with no time limit. This test usually takes several hours, depending on the read/write speed of the drive and its size. It is possible for the long test to pass even if the short test fails.&lt;/li&gt; &lt;li&gt;Conveyance: Intended as a quick test to identify damage incurred during transporting of the device from the drive manufacturer to the computer manufacturer. Only available on ATA drives, and it usually takes several minutes.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Drives remain operable during self-test, unless a &#34;captive&#34; option (ATA only) is requested.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Long test&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Start with a long self test with &lt;code&gt;smartctl&lt;/code&gt;. Assuming the disk to test is &lt;code&gt;/dev/sdd&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;smartctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;long&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The command will respond with an estimate of how long it thinks the test will take to complete.&lt;/p&gt; &lt;p&gt;To check progress use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;martctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-A&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;remaining
smartctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;remaining
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Don&#39;t check too often because it can abort the test with some drives. If you receive an empty output, examine the reported status with:&lt;/p&gt; &lt;p&gt;&lt;code&gt;`bash smartctl -l selftest /dev/sdd&lt;/code&gt;&lt;/p&gt; &lt;p&gt;If errors are shown, check the &lt;code&gt;dmesg&lt;/code&gt; as there are usually useful traces of the error.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/smartctl/#understanding-the-tests&#34;&gt;Understanding the tests.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The output of a &lt;code&gt;smartctl&lt;/code&gt; command is difficult to read:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;smartctl 5.40 2010-03-16 r3077 [x86_64-unknown-linux-gnu] (local build)
Copyright (C) 2002-10 by Bruce Allen, http://smartmontools.sourceforge.net

=== START OF INFORMATION SECTION ===
Model Family:     SAMSUNG SpinPoint F2 EG series
Device Model:     SAMSUNG HD502HI
Serial Number:    S1VZJ9CS712490
Firmware Version: 1AG01118
User Capacity:    500,107,862,016 bytes
Device is:        In smartctl database [for details use: -P show]
ATA Version is:   8
ATA Standard is:  ATA-8-ACS revision 3b
Local Time is:    Wed Feb  9 15:30:42 2011 CET
SMART support is: Available - device has SMART capability.
SMART support is: Enabled

=== START OF READ SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED

General SMART Values:
Offline data collection status:  (0x00)    Offline data collection activity
                    was never started.
                    Auto Offline Data Collection: Disabled.
Self-test execution status:      (   0)    The previous self-test routine completed
                    without error or no self-test has ever
                    been run.
Total time to complete Offline
data collection:          (6312) seconds.
Offline data collection
capabilities:              (0x7b) SMART execute Offline immediate.
                    Auto Offline data collection on/off support.
                    Suspend Offline collection upon new
                    command.
                    Offline surface scan supported.
                    Self-test supported.
                    Conveyance Self-test supported.
                    Selective Self-test supported.
SMART capabilities:            (0x0003)    Saves SMART data before entering
                    power-saving mode.
                    Supports SMART auto save timer.
Error logging capability:        (0x01)    Error logging supported.
                    General Purpose Logging supported.
Short self-test routine
recommended polling time:      (   2) minutes.
Extended self-test routine
recommended polling time:      ( 106) minutes.
Conveyance self-test routine
recommended polling time:      (  12) minutes.
SCT capabilities:            (0x003f)    SCT Status supported.
                    SCT Error Recovery Control supported.
                    SCT Feature Control supported.
                    SCT Data Table supported.

SMART Attributes Data Structure revision number: 16
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x000f   099   099   051    Pre-fail  Always       -       2376
  3 Spin_Up_Time            0x0007   091   091   011    Pre-fail  Always       -       3620
  4 Start_Stop_Count        0x0032   100   100   000    Old_age   Always       -       405
  5 Reallocated_Sector_Ct   0x0033   100   100   010    Pre-fail  Always       -       0
  7 Seek_Error_Rate         0x000f   253   253   051    Pre-fail  Always       -       0
  8 Seek_Time_Performance   0x0025   100   100   015    Pre-fail  Offline      -       0
  9 Power_On_Hours          0x0032   100   100   000    Old_age   Always       -       717
 10 Spin_Retry_Count        0x0033   100   100   051    Pre-fail  Always       -       0
 11 Calibration_Retry_Count 0x0012   100   100   000    Old_age   Always       -       0
 12 Power_Cycle_Count       0x0032   100   100   000    Old_age   Always       -       405
 13 Read_Soft_Error_Rate    0x000e   099   099   000    Old_age   Always       -       2375
183 Runtime_Bad_Block       0x0032   100   100   000    Old_age   Always       -       0
84 End-to-End_Error        0x0033   100   100   000    Pre-fail  Always       -       0
187 Reported_Uncorrect      0x0032   100   100   000    Old_age   Always       -       2375
188 Command_Timeout         0x0032   100   100   000    Old_age   Always       -       0
190 Airflow_Temperature_Cel 0x0022   084   074   000    Old_age   Always       -       16 (Lifetime Min/Max 16/16)
194 Temperature_Celsius     0x0022   084   071   000    Old_age   Always       -       16 (Lifetime Min/Max 16/16)
195 Hardware_ECC_Recovered  0x001a   100   100   000    Old_age   Always       -       3558
196 Reallocated_Event_Count 0x0032   100   100   000    Old_age   Always       -       0
197 Current_Pending_Sector  0x0012   098   098   000    Old_age   Always       -       81
198 Offline_Uncorrectable   0x0030   100   100   000    Old_age   Offline      -       0
199 UDMA_CRC_Error_Count    0x003e   100   100   000    Old_age   Always       -       1
200 Multi_Zone_Error_Rate   0x000a   100   100   000    Old_age   Always       -       0
201 Soft_Read_Error_Rate    0x000a   253   253   000    Old_age   Always       -       0

MART Error Log Version: 1
No Errors Logged

SMART Self-test log structure revision number 1
No self-tests have been logged.  [To run self-tests, use: smartctl -t]

SMART Selective self-test log data structure revision number 1
 SPAN  MIN_LBA  MAX_LBA  CURRENT_TEST_STATUS
    1        0        0  Not_testing
    2        0        0  Not_testing
    3        0        0  Not_testing
    4        0        0  Not_testing
    5        0        0  Not_testing
Selective self-test flags (0x0):
  After scanning selected spans, do NOT read-scan remainder of disk.
If Selective self-test is pending on power-up, resume after 0 minute delay.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Checking overall health&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Somewhere in your report you&#39;ll see something like:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;=== START OF READ SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If it doesn’t return PASSED, you should immediately backup all your data. Your hard drive is probably failing.&lt;/p&gt; &lt;p&gt;That message can also be shown with &lt;code&gt;smartctl -H /dev/sda&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Self-Monitoring,_Analysis_and_Reporting_Technology#Known_ATA_S.M.A.R.T._attributes&#34;&gt;Checking the SMART attributes&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Each drive manufacturer defines a set of attributes, and sets threshold values beyond which attributes should not pass under normal operation. But they do not agree on precise attribute definitions and measurement units, the following list of attributes is a general guide only.&lt;/p&gt; &lt;p&gt;If one or more attribute have the &#34;prefailure&#34; flag, and the &#34;current value&#34; of such prefailure attribute is smaller than or equal to its &#34;threshold value&#34; (unless the &#34;threshold value&#34; is 0), that will be reported as a &#34;drive failure&#34;. In addition, a utility software can send SMART RETURN STATUS command to the ATA drive, it may report three status: &#34;drive OK&#34;, &#34;drive warning&#34; or &#34;drive failure&#34;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://ma.juii.net/blog/interpret-smart-attributes&#34;&gt;SMART attributes columns&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Every of the SMART attributes has several columns as shown by “smartctl -a &lt;device&gt;”:&lt;/device&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;ID: The ID number of the attribute, good for comparing with other lists like &lt;a href=&#34;https://en.wikipedia.org/wiki/Self-Monitoring,_Analysis_and_Reporting_Technology#Known_ATA_S.M.A.R.T._attributes&#34;&gt;Wikipedia: S.M.A.R.T.: Known ATA S.M.A.R.T. attributes&lt;/a&gt; because the attribute names sometimes differ. Name: The name of the SMART attribute.&lt;/li&gt; &lt;li&gt;Value: The current, normalized value of the attribute. Higher values are always better (except for temperature for hard disks of some manufacturers). The range is normally 0-100, for some attributes 0-255 (so that 100 resp. 255 is best, 0 is worst). There is no standard on how manufacturers convert their raw value to this normalized one: when the normalized value approaches threshold, it can do linearily, exponentially, logarithmically or any other way, meaning that a doubled normalized value does not necessarily mean “twice as good”.&lt;/li&gt; &lt;li&gt;Worst: The worst (normalized) value that this attribute had at any point of time where SMART was enabled. There seems to be no mechanism to reset current SMART attribute values, but this still makes sense as some SMART attributes, for some manufacturers, fluctuate over time so that keeping the worst one ever is meaningful.&lt;/li&gt; &lt;li&gt;Threshold: The threshold below which the normalized value will be considered “exceeding specifications”. If the attribute type is “Pre-fail”, this means that SMART thinks the hard disk is just before failure. This will “trigger” SMART: setting it from “SMART test passed” to “SMART impending failure” or similar status.&lt;/li&gt; &lt;li&gt;Type: The type of the attribute. Either “Pre-fail” for attributes that are said to indicate impending failure, or “Old_age” for attributes that just indicate wear and tear. Note that one and the same attribute can be classified as “Pre-fail” by one manufacturer or for one model and as “Old_age” by another or for another model. This is the case for example for attribute Seek_Error_Rate (ID 7), which is a widespread phenomenon on many disks and not considered critical by some manufacturers, but Seagate has it as “Pre-fail”.&lt;/li&gt; &lt;li&gt;Raw value: The current raw value that was converted to the normalized value above. smartctl shows all as decimal values, but some attribute values of some manufacturers cannot be reasonably interpreted that way&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/smartctl/#reacting-to-smart-values&#34;&gt;Reacting to SMART Values.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It is said that a drive that starts getting bad sectors (attribute ID 5) or “pending” bad sectors (attribute ID 197; they most likely are bad, too) will usually be trash in 6 months or less. The only exception would be if this does not happen: that is, bad sector count increases, but then stays stable for a long time, like a year or more. For that reason, one normally needs a diagramming / journaling tool for SMART. Many admins will exchange the hard drive if it gets reallocated sectors (ID 5) or sectors “under investigation” (ID 197)&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Self-Monitoring,_Analysis_and_Reporting_Technology#Known_ATA_S.M.A.R.T._attributes&#34;&gt;Critical SMART attributes&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Of all the attributes I&#39;m going to analyse only the critical ones&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Read Error Rate&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;ID: 01 (0x01) deal: Low +Correlation with probability of failure: not clear&lt;/p&gt; &lt;p&gt;(Vendor specific raw value.) Stores data related to the rate of hardware read errors that occurred when reading data from a disk surface. The raw value has different structure for different vendors and is often not meaningful as a decimal number. For some drives, this number may increase during normal operation without necessarily signifying errors.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Reallocated Sectors Count&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;ID: 05 (0x05) Ideal: Low Correlation with probability of failure: Strong&lt;/p&gt; &lt;p&gt;Count of reallocated sectors. The raw value represents a count of the bad sectors that have been found and remapped. Thus, the higher the attribute value, the more sectors the drive has had to reallocate. This value is primarily used as a metric of the life expectancy of the drive; a drive which has had any reallocations at all is significantly more likely to fail in the immediate months. If Raw value of 0x05 attribute is higher than its Threshold value, that will reported as &#34;drive warning&#34;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Spin Retry Count&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;ID: 10 (0x0A) Ideal: Low Correlation with probability of failure: Strong&lt;/p&gt; &lt;p&gt;Count of retry of spin start attempts. This attribute stores a total count of the spin start attempts to reach the fully operational speed (under the condition that the first attempt was unsuccessful). An increase of this attribute value is a sign of problems in the hard disk mechanical subsystem.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Current Pending Sector Count&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;ID: 197 (0xC5) Ideal: Low Correlation with probability of failure: Strong&lt;/p&gt; &lt;p&gt;Count of &#34;unstable&#34; sectors (waiting to be remapped, because of unrecoverable read errors). If an unstable sector is subsequently read successfully, the sector is remapped and this value is decreased. Read errors on a sector will not remap the sector immediately (since the correct value cannot be read and so the value to remap is not known, and also it might become readable later); instead, the drive firmware remembers that the sector needs to be remapped, and will remap it the next time it has been successfully read.[76]&lt;/p&gt; &lt;p&gt;However, some drives will not immediately remap such sectors when successfully read; instead the drive will first attempt to write to the problem sector, and if the write operation is successful the sector will then be marked as good (in this case, the &#34;Reallocation Event Count&#34; (0xC4) will not be increased). This is a serious shortcoming, for if such a drive contains marginal sectors that consistently fail only after some time has passed following a successful write operation, then the drive will never remap these problem sectors. If Raw value of 0xC5 attribute is higher than its Threshold value, that will reported as &#34;drive warning&#34;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;(Offline) Uncorrectable Sector Count&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;ID: 198 (0xC6) Ideal: Low Correlation with probability of failure: Strong&lt;/p&gt; &lt;p&gt;The total count of uncorrectable errors when reading/writing a sector. A rise in the value of this attribute indicates defects of the disk surface and/or problems in the mechanical subsystem.&lt;/p&gt; &lt;p&gt;In the 60 days following the first uncorrectable error on a drive (S.M.A.R.T. attribute 0xC6 or 198) detected as a result of an offline scan, the drive was, on average, 39 times more likely to fail than a similar drive for which no such error occurred.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Non critical SMART attributes&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The next attributes appear to change in the logs but that doesn&#39;t mean that there is anything going wrong&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Hardware ECC Recovered&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;ID: 195 (0xC3) Ideal: Varies Correlation with probability of failure: Low&lt;/p&gt; &lt;p&gt;(Vendor-specific raw value.) The raw value has different structure for different vendors and is often not meaningful as a decimal number. For some drives, this number may increase during normal operation without necessarily signifying errors.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/smartctl/#monitorization&#34;&gt;Monitorization.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To monitor your drive health you can use &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/prometheus/&#34;&gt;prometheus&lt;/a&gt; with &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/alertmanager/&#34;&gt;alertmanager&lt;/a&gt; for alerts and &lt;a href=&#34;https://lyz-code.github.io/blue-book/grafana/&#34;&gt;grafana&lt;/a&gt; for dashboards.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Installing the exporter&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The prometheus community has it&#39;s own &lt;a href=&#34;https://github.com/prometheus-community/smartctl_exporter&#34;&gt;smartctl exporter&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Using the binary&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can download the latest binary from the repository &lt;a href=&#34;https://github.com/prometheus-community/smartctl_exporter/releases&#34;&gt;releases&lt;/a&gt; and configure the &lt;a href=&#34;https://github.com/prometheus-community/smartctl_exporter/blob/master/systemd/smartctl_exporter.service&#34;&gt;systemd service&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;unp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;smartctl_exporter-0.13.0.linux-amd64.tar.gz
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;smartctl_exporter-0.13.0.linux-amd64/smartctl_exporter&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/usr/bin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Add the &lt;a href=&#34;https://github.com/prometheus-community/smartctl_exporter/blob/master/systemd/smartctl_exporter.service&#34;&gt;service&lt;/a&gt; to &lt;code&gt;/etc/systemd/system/smartctl-exporter.service&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[Unit]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;smartctl exporter service&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;After&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;network-online.target&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Service]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;simple&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;PIDFile&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/run/smartctl_exporter.pid&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;ExecStart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/usr/bin/smartctl_exporter&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;User&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;root&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Group&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;root&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;SyslogIdentifier&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;smartctl_exporter&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Restart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;on-failure&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;RemainAfterExit&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;no&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;RestartSec&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;100ms&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;StandardOutput&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;journal&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;StandardError&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;journal&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Install]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;WantedBy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;multi-user.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;hen enable it:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;enable&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;smartctl-exporter
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;service&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;smartctl-exporter&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/prometheus-community/smartctl_exporter?tab=readme-ov-file#example-of-running-in-docker&#34;&gt;Using docker&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;smartctl-exporter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;container_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl-exporter&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;prometheuscommunity/smartctl-exporter&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;privileged&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;root&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ports&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;9633:9633&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Configuring prometheus&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Add the next scraping metrics:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;job_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl_exporter&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metrics_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/metrics&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;scrape_timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;60s&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;static_configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;targets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;smartctl-exporter&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;9633&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;hostname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;your-hostname&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Configuring the alerts&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Taking as a reference the &lt;a href=&#34;https://samber.github.io/awesome-prometheus-alerts/rules#s.m.a.r.t-device-monitoring&#34;&gt;awesome prometheus rules&lt;/a&gt; and &lt;a href=&#34;https://www.wirewd.com/hacks/blog/monitoring_a_mixed_fleet_of_flash_hdd_and_nvme_devices_with_node_exporter_and_prometheus&#34;&gt;this wired post&lt;/a&gt; I&#39;m using the next rules:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;groups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl exporter&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;SmartDeviceTemperatureWarning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl_device_temperature &amp;gt; 60&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;2m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;w w-Error&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;w w-Error&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Smart device temperature warning (instance {{ $labels.hostname }})&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;Device&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;temperature&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;warning&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;SmartDeviceTemperatureCritical&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl_device_temperature &amp;gt; 80&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;2m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;critical&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Smart device temperature critical (instance {{ $labels.hostname }})&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;Device&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;temperature&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;critical&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;SmartCriticalWarning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl_device_critical_warning &amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;15m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;critical&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Smart critical warning (instance {{ $labels.hostname }})&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;device&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;has&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;critical&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;warning&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;SmartNvmeWearoutIndicator&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl_device_available_spare{device=~&#34;nvme.*&#34;} &amp;lt; smartctl_device_available_spare_threshold{device=~&#34;nvme.*&#34;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;15m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;critical&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Smart NVME Wearout Indicator (instance {{ $labels.hostname }})&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;NVMe&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;device&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;wearing&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;SmartNvmeMediaError&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl_device_media_errors &amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;15m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;w w-Error&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Smart NVME Media errors (instance {{ $labels.hostname }})&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;Contains&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;the&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;number&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;of&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;occurrences&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;where&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;the&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;controller&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;detected&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;an&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;unrecovered&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;integrity&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;error.&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Errors&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;such&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;as&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;uncorrectable&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;ECC,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;CRC&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;checksum&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;failure,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;or&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LBA&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;tag&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;mismatch&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;are&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;included&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;field&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;SmartSmartStatusError&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl_device_smart_status &amp;lt; 1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;15m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;critical&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Smart general status error (instance {{ $labels.hostname }})&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;w w-Error&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;DiskReallocatedSectorsIncreased&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl_device_attribute{attribute_id=&#34;5&#34;, attribute_value_type=&#34;raw&#34;} &amp;gt; max_over_time(smartctl_device_attribute{attribute_id=&#34;5&#34;, attribute_value_type=&#34;raw&#34;}[1h])&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;w w-Error&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;SMART&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Attribute&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Reallocated&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Sectors&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Count&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Increased&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;SMART&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;attribute&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(Reallocated&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Sectors&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Count)&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;has&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;increased&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.device&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;w w-Error&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;DiskSpinRetryCountIncreased&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl_device_attribute{attribute_id=&#34;10&#34;, attribute_value_type=&#34;raw&#34;} &amp;gt; max_over_time(smartctl_device_attribute{attribute_id=&#34;10&#34;, attribute_value_type=&#34;raw&#34;}[1h])&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;SMART&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Attribute&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Spin&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Retry&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Count&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Increased&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;SMART&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;attribute&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(Spin&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Retry&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Count)&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;has&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;increased&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.device&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;DiskCurrentPendingSectorCountIncreased&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl_device_attribute{attribute_id=&#34;197&#34;, attribute_value_type=&#34;raw&#34;} &amp;gt; max_over_time(smartctl_device_attribute{attribute_id=&#34;197&#34;, attribute_value_type=&#34;raw&#34;}[1h])&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;SMART&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Attribute&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Current&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Pending&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Sector&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Count&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Increased&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;SMART&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;attribute&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;197&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(Current&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Pending&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Sector&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Count)&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;has&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;increased&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.device&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;DiskUncorrectableSectorCountIncreased&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl_device_attribute{attribute_id=&#34;198&#34;, attribute_value_type=&#34;raw&#34;} &amp;gt; max_over_time(smartctl_device_attribute{attribute_id=&#34;198&#34;, attribute_value_type=&#34;raw&#34;}[1h])&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;SMART&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Attribute&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Uncorrectable&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Sector&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Count&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Increased&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;SMART&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;attribute&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;198&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(Uncorrectable&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Sector&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Count)&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;has&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;increased&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.device&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Configuring the grafana dashboards&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Of the different grafana dashboards (&lt;a href=&#34;https://grafana.com/grafana/dashboards/22604-smartctl-exporter-dashboard/&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;https://grafana.com/grafana/dashboards/20204-smart-hdd/&#34;&gt;2&lt;/a&gt;, &lt;a href=&#34;https://grafana.com/grafana/dashboards/22381-smartctl-exporter/&#34;&gt;3&lt;/a&gt;) I went for the first one.&lt;/p&gt; &lt;p&gt;Import it with the UI of grafana, make it work and then export the json to store it in your infra as code respository.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Self-Monitoring,_Analysis_and_Reporting_Technology&#34;&gt;Wikipedia&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://sourceforge.net/projects/smartmontools/&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.smartmontools.org/wiki/TocDoc&#34;&gt;Documentation&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/zfs_storage_planning/#thoughts-on-adding-new-disks-to-zfs&#34;&gt;Thoughts on adding new disks to ZFS.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;When it comes to expanding an existing ZFS storage system, careful consideration is crucial. In my case, I faced a decision point with my storage cluster: after two years of reliable service from my 8TB drives, I needed more capacity. This led me to investigate the best way to integrate newly acquired refurbished 12TB drives into the system. Here&#39;s my journey through this decision-making process and the insights gained along the way.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;The Starting Point&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;My existing setup consisted of 8TB drives purchased new, which had been running smoothly for two years. The need for expansion led me to consider refurbished 12TB drives as a cost-effective solution. However, mixing new and refurbished drives, especially of different capacities, raised several important considerations that needed careful analysis.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Initial Drive Assessment&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The first step was to evaluate the reliability of all drives. Using &lt;code&gt;smartctl&lt;/code&gt;, I analyzed the SMART data across both the existing and new drives:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;disk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;b&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;e&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;g&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;h&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;i&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;/dev/sd&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$disk&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: old &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;smartctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sd&lt;span class=&#34;nv&#34;&gt;$disk&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Old&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; pre-fail: &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;smartctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sd&lt;span class=&#34;nv&#34;&gt;$disk&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Pre-&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The results showed similar values across all drives, with &#34;Old_Age&#34; attributes ranging from 14-17 and &#34;Pre-fail&#34; attributes between 3-6. While this indicated all drives were aging, they were still functioning with acceptable parameters. However, raw SMART data doesn&#39;t tell the whole story, especially when comparing new versus refurbished drives.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Drive Reliability Considerations&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;After careful evaluation, I found myself trusting the existing 8TB drives more than the newer refurbished 12TB ones. This conclusion was based on several factors:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The 8TB drives had a proven track record in my specific environment&lt;/li&gt; &lt;li&gt;Their smaller size meant faster resilver times, reducing the window of vulnerability during recovery&lt;/li&gt; &lt;li&gt;One of the refurbished 12TB drives was already showing concerning symptoms (8 reallocated sectors, although a badblocks didn&#39;t increase that number), which reduced confidence in the entire batch&lt;/li&gt; &lt;li&gt;The existing drives were purchased new, while the 12TB drives were refurbished, adding an extra layer of uncertainty&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Layout Options Analysis&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;When expanding a ZFS system, there&#39;s always the temptation to simply add more vdevs to the existing pool. However, I investigated two main approaches:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Creating a new separate ZFS pool with the new disks&lt;/li&gt; &lt;li&gt;Add another vdev to the existent pool&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;strong&gt;Resilver time&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Adding the 12TB drives to the pool and redistributing the data across all 8 drives will help reduce the resilver time. Here&#39;s a detailed breakdown:&lt;/p&gt; &lt;ol&gt; &lt;li&gt; &lt;p&gt;&lt;strong&gt;Current Situation&lt;/strong&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;4x 8TB drives at 95% capacity means each drive is heavily packed&lt;/p&gt; &lt;/li&gt; &lt;li&gt;High data density means longer resilver times&lt;/li&gt; &lt;li&gt; &lt;p&gt;Limited free space for data movement and reconstruction&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;strong&gt;After Adding 12TB Drives&lt;/strong&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Total pool capacity increases significantly&lt;/p&gt; &lt;/li&gt; &lt;li&gt;ZFS will automatically start rebalancing data across all 8 drives&lt;/li&gt; &lt;li&gt;This process (sometimes called &#34;data shuffling&#34; or &#34;data redistribution&#34;) has several benefits:&lt;/li&gt; &lt;li&gt;Reduces data density per drive&lt;/li&gt; &lt;li&gt;Creates more free space&lt;/li&gt; &lt;li&gt;Improves overall pool performance&lt;/li&gt; &lt;li&gt; &lt;p&gt;Potentially reduces future resilver times&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;strong&gt;Resilver Time Reduction Mechanism&lt;/strong&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;With data spread across more drives, each individual drive has less data to resilver&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Less data per drive = faster resilver process&lt;/li&gt; &lt;li&gt;The redistribution happens gradually and in the background&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;strong&gt;Understanding Failure Scenarios&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The key differentiator between these approaches came down to failure scenarios:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Single Drive Failure&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Both configurations handle single drive failures similarly, though the 12TB drives&#39; longer resilver time creates a longer window of vulnerability in the two-vdev configuration if the data load is evenly shared between the disks. This is particularly concerning with refurbished drives, where the failure probability might be higher.&lt;/p&gt; &lt;p&gt;However if as soon as you add the other vdev to the pool you defragment the data inside zfs, the 8TB drives will be less filled, so until more data is added you may reduce the resilver time as they have less data.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Double Drive Failure&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;This is where the configurations differ significantly:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;In a two-vdev pool, losing two drives from the same vdev would cause complete pool failure&lt;/li&gt; &lt;li&gt;With separate pools, a double drive failure would only affect one pool, allowing the other to continue operating. This way you can store the critical data on the pool you trust more.&lt;/li&gt; &lt;li&gt;Given the mixed drive origins (new vs refurbished), isolating potential failures becomes more critical&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Performance Considerations&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;While investigating performance implications, I found several interesting points about IOPS and throughput:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;ZFS stripes data across vdevs, meaning more vdevs generally means better IOPS&lt;/li&gt; &lt;li&gt;In RAIDZ configurations, IOPS are limited by the slowest drive in the vdev&lt;/li&gt; &lt;li&gt;Multiple mirrored vdevs provide the best combined IOPS performance&lt;/li&gt; &lt;li&gt;Streaming speeds scale with the number of data disks in a RAIDZ vdev&lt;/li&gt; &lt;li&gt;When mixing drive sizes, ZFS tends to favor larger vdevs, which could lead to uneven wear&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Easiness of configuration&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Cache and log&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you already have a zpool with a cache and logs in nvme, then if you were to use two pools, you&#39;d need to reformat your nvme drives to create space for the new partitions needed for the new zpool.&lt;/p&gt; &lt;p&gt;This would allow you to specify different cache sizes for each pool. But it comes at the cost of a more complex operation.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;New pool creation&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Adding a vdev to an existing pool is quicker and easier than to create a zpool. You need to make sure that you initialise it with the correct configuration.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Storage management&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Having two pools doubles the operation tasks. One of the pools are to be filled soon, so you may need to manually move files and directories around to rebalance it.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Final Decision&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;After weighing all factors, if you favour reliability over easiness of your life implement two separate ZFS pools. This statement is primarily driven by:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Enhanced Reliability&lt;/strong&gt;: By separating the pools, we can maintain service availability even if one pool fails completely&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Data Prioritization&lt;/strong&gt;: This allows placing critical application data on the more reliable pool (8TB drives), while using the refurbished drives for less critical data like media files&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Risk Isolation&lt;/strong&gt;: Keeping the proven, new-purchased drives separate from the refurbished ones minimizes the impact of potential issues with the refurbished drives&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Consistent Performance&lt;/strong&gt;: Following the best practice of keeping same-sized drives together in pools&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;However I&#39;m currently favouring easiness of life and trust my backup solution (I hope not to read this line in the future with regret :P), so I&#39;ll go with two vdevs.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Key Takeaways&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Through this investigation, I learned several important lessons about ZFS storage design:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Raw parity drive count isn&#39;t the only reliability metric - configuration matters more than simple redundancy numbers&lt;/li&gt; &lt;li&gt;Pool layout significantly impacts both performance and failure scenarios&lt;/li&gt; &lt;li&gt;Sometimes simpler configurations (like separate pools) can provide better overall reliability than more complex ones&lt;/li&gt; &lt;li&gt;Consider the full lifecycle of the storage, including maintenance operations like resilver times&lt;/li&gt; &lt;li&gt;When expanding storage, don&#39;t underestimate the value of isolating different generations or sources of hardware&lt;/li&gt; &lt;li&gt;The history and source of drives (new vs refurbished) should influence your pool design decisions&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;This investigation reinforced that storage design isn&#39;t just about maximizing space or performance - it&#39;s about finding the right balance of reliability, performance, and manageability for your specific needs. When dealing with mixed drive sources and different capacities, this balance becomes even more critical.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References and further reading&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.truenas.com/blog/zfs-pool-performance-2/&#34;&gt;Truenas post&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://forums.freebsd.org/threads/when-does-it-make-more-sense-to-use-multiple-vdevs-in-a-zfs-pool.83586/&#34;&gt;Freebsd post&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://klarasystems.com/articles/choosing-the-right-zfs-pool-layout/&#34;&gt;Klarasystems post&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;diff --git a/mkdocs.yml b/mkdocs.yml index 74292dd717..596f1506e8 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -103,6 +103,8 @@ nav: - Email clients: - himalaya: himalaya.md - alot: alot.md + - k9: k9.md + - Email protocols: - Maildir: maildir.md - Instant Messages Management: @@ -371,6 +373,7 @@ nav: - File management configuration: - NeoTree: neotree.md - Telescope: telescope.md + - fzf.nvim: fzf_nvim.md - Editing specific configuration: - vim_editor_plugins.md - Vim formatters: vim_formatters.md @@ -566,7 +569,10 @@ nav: - OpenZFS storage planning: zfs_storage_planning.md - Sanoid: sanoid.md - ZFS Prometheus exporter: zfs_exporter.md - - Hard drive health: hard_drive_health.md + - Hard drive health: + - hard_drive_health.md + - Smartctl: smartctl.md + - badblocks: badblocks.md - Resilience: - linux_resilience.md - Memtest: memtest.md @@ -768,7 +774,8 @@ nav: # - Streaming channels: streaming_channels.md - Music: - Sister Rosetta Tharpe: sister_rosetta_tharpe.md - - Video Gaming: + - Videogames: + - DragonSweeper: dragonsweeper.md - King Arthur Gold: kag.md - The Battle for Wesnoth: - The Battle for Wesnoth: wesnoth.md&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add link tot he backblaze disk reports.&lt;/p&gt; &lt;p&gt;If you have some time take a look at &lt;a href=&#34;https://www.backblaze.com/cloud-storage/resources/hard-drive-test-data&#34;&gt;backblaze disk reports&lt;/a&gt; they do quarterly analysis on their infra (around 300k disks).&lt;/p&gt; &lt;p&gt;@@ -26,6 +26,7 @@ nav: - Feminism: - Privileges: feminism/privileges.md - Palestine: palestine.md + - Detección de estupas: estupas.md - Anarchism: anarchism.md - Memoria histórica: memoria_historica.md - Anti-Tourism: antitourism.md @@ -33,19 +34,22 @@ nav: - Free Knowledge: free_knowledge.md - Free Software: free_software.md - Environmentalism: environmentalism.md - - Laboral: - - laboral.md - - Trabajadoras del hogar: trabajadoras_del_hogar.md + - Laboral: + - laboral.md + - Trabajadoras del hogar: trabajadoras_del_hogar.md - Collaborating tools: collaborating_tools.md - Conference organisation: - conference_organisation.md - pretalx: pretalx.md - - Ludditest: luddites.md - - Life Management: + - Luddites: luddites.md + - Life navigation: - life_management.md - - Time management: + - Time navigation: - time_management.md - - Time management abstraction levels: time_management_abstraction_levels.md + - Time navigation abstraction levels: + - time_management_abstraction_levels.md + - Identities: identities.md + - Axis: axis.md - Action Management: action_management.md - Roadmap Adjustment: - roadmap_adjustment.md @@ -134,6 +138,7 @@ nav: - Book Management: - book_management.md - Bookwyrm: bookwyrm.md + - Book DRM: book_drm.md - Movies Management: - Jellyfin: jellyfin.md - Ombi: ombi.md @@ -196,6 +201,7 @@ nav: - Teeth: - teeth.md - Deep cleaning: teeth_deep_cleaning.md + - Silence: silence.md - Remote Working: remote_work.md - Fitness Tracker: - fitness_band.md @@ -649,6 +655,8 @@ nav: - fail2ban: linux/fail2ban.md - pass: pass.md - Wireshark: wireshark.md + - Canary tokens: canary_tokens.md + - Sysadmin tools: - brew: linux/brew.md - detox: detox.md @@ -753,6 +761,7 @@ nav: - Speech to text: - Whisper: whisper.md - Speech recognition: speech_recognition.md + - Text to speech: text_to_speech.md - Coding by Voice: coding_by_voice.md - Data Analysis: - data_analysis.md&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/aws/aws/#remove-the-public-ip-of-an-ec2-instance&#34;&gt;Remove the public IP of an ec2 instance.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Navigate to the network interfaces of the instance&lt;/li&gt; &lt;li&gt;Click on the one that contains the public IP&lt;/li&gt; &lt;li&gt;Actions/Manage IP addresses&lt;/li&gt; &lt;li&gt;Click on the Interface to unfold the configuration&lt;/li&gt; &lt;li&gt;Click on Auto-assign public IP&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce vector.&lt;/p&gt; &lt;p&gt;Vector is a lightweight, ultra-fast tool for building observability pipelines&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://vector.dev/docs/setup/installation/package-managers/apt/&#34;&gt;On debian&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;First, add the Vector repo:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;bash&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-L&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://setup.vector.dev&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then you can install the vector package:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;vector
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Tweak the configuration and then enable the service.&lt;/p&gt; &lt;p&gt;To be sure that vector is able to push to loki create the &lt;code&gt;/usr/local/bin/wait-for-loki.sh&lt;/code&gt; file&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;true&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;http://localhost:3100/ready&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$response&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;ready&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;sleep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Make it executable &lt;code&gt;chmod +x /usr/local/bin/wait-for-loki.sh&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Then update your &lt;code&gt;vector.service&lt;/code&gt; (&lt;code&gt;/usr/lib/systemd/system/vector.service&lt;/code&gt;)&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ExecStartPre=/usr/local/bin/wait-for-loki.sh
ExecStartPre=/usr/bin/vector validate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Run &lt;code&gt;systemctl daemon-reload&lt;/code&gt; to reload the service configuration.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://vector.dev/docs/reference/configuration/&#34;&gt;Configuration&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The config lives at &lt;code&gt;/etc/vector/vector.yaml&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://vector.dev/docs/reference/configuration/sources/docker_logs/&#34;&gt;Docker&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;First add &lt;code&gt;vector&lt;/code&gt; to the &lt;code&gt;docker&lt;/code&gt; group: &lt;code&gt;usermod -a -G docker vector&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;sources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;docker&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;docker_logs&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;transforms&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;docker_labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;remap&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;inputs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;docker&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;.service_name = get(.label, [&#34;com.docker.compose.project&#34;]) ?? &#34;unknown&#34;&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;sinks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;loki_docker&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;loki&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;inputs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;docker_labels&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;endpoint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;http://localhost:3100/&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;encoding&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;codec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;json&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;docker&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;host&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;host&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;container&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;container_name&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;service_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;service_name&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://vector.dev/docs/reference/configuration/sources/journald/&#34;&gt;journald&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To avoid the services that run docker to be indexed twice&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;sources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;journald&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;journald&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;transforms&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;journald_filter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;filter&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;inputs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;journald&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;condition&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;# Exclude docker-compose systemd services&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;!contains(string!(.SYSLOG_IDENTIFIER), &#34;docker-compose&#34;) &amp;amp;&amp;amp;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;!contains(string!(.SYSLOG_IDENTIFIER), &#34;docker&#34;)&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;journald_labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;remap&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;inputs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;journald_filter&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;.service_name = ._SYSTEMD_UNIT || &#34;unknown&#34;&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;sinks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;loki_systemd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;loki&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;inputs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;journald_labels&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;endpoint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;http://localhost:3100/&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;encoding&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;codec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;json&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;journald&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;host&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;host&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;service_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;service_name&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;ZFS&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Prepare the file to be readable by vector:&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;chown&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;root:vector&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/spl/kstat/zfs/dbgmsg
chmod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;640&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/spl/kstat/zfs/dbgmsg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;sources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;zfs_log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;file&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;include&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/proc/spl/kstat/zfs/dbgmsg&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;zfs_files&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;loki&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;inputs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;zfs_log&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;endpoint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;http://localhost:3100/&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;encoding&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;codec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;json&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;file&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;service_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;zfs&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;host&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;host&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;sinks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;strong&gt;Troubleshooting&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Unable to open checkpoint file. path=&#34;/var/lib/vector/journald/checkpoint.txt&#34;&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ERROR source{component_kind=&#34;source&#34; component_id=journald component_type=journald}: vector::internal_events::journald: Unable to open checkpoint file. path=&#34;/var/lib/vector/journald/checkpoint.txt&#34; error=Permission denied (os error 13) error_type=&#34;io_failed&#34; stage=&#34;receiving&#34;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mkdir&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/vector/journald
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;chown&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-R&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;vector:vector&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/vector
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;chmod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;755&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/vector
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;chmod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;755&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/vector/journald
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://vector.dev/&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vector/#vector-permission-debugging-with-systemd-tmpfiles&#34;&gt;Vector Permission Debugging with systemd tmpfiles.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Vector fails to read log files after reboots or log rotation with permission errors:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ERROR: Failed reading file for fingerprinting. error=Permission denied (os error 13)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Solution with tmpfiles&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Create &lt;code&gt;/etc/tmpfiles.d/vector-permissions.conf&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;z /data/apps/myapp/logs/logfile.log 0644 vector vector -
z /path/to/another/logfile.log 0644 vector vector -
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Apply immediately:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;systemd-tmpfiles&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--create&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/tmpfiles.d/vector-permissions.conf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;What is tmpfiles&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;systemd tmpfiles.d is a mechanism for managing temporary files, directories, and their permissions at boot time and periodically during system operation.&lt;/p&gt; &lt;p&gt;What it does:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Creates/removes files and directories&lt;/li&gt; &lt;li&gt;Sets ownership and permissions&lt;/li&gt; &lt;li&gt;Runs at boot via systemd-tmpfiles-setup.service&lt;/li&gt; &lt;li&gt;Can be triggered manually or periodically&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Configuration format:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Type Path Mode UID GID Age Argument
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Common types:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;d&lt;/code&gt; - Create directory&lt;/li&gt; &lt;li&gt;&lt;code&gt;f&lt;/code&gt; - Create file&lt;/li&gt; &lt;li&gt;&lt;code&gt;z&lt;/code&gt; - Set ownership/permissions on existing path&lt;/li&gt; &lt;li&gt;&lt;code&gt;Z&lt;/code&gt; - Recursively set ownership/permissions&lt;/li&gt; &lt;li&gt;&lt;code&gt;x&lt;/code&gt; - Ignore/exclude path&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;d /var/run/myapp 0755 myuser mygroup -
f /var/log/myapp.log 0644 myuser mygroup -
z /existing/file 0644 myuser mygroup -
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Files in /etc/tmpfiles.d/ with .conf extension are processed automatically at boot and can be manually applied with systemd-tmpfiles --create. Also, if the &lt;code&gt;systemd-tmpfiles-clean.timer&lt;/code&gt; is enabled (which is by default) it will be check each day.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;openzfs&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/&#34;&gt;OpenZFS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/badblocks/#check-the-health-of-a-disk-with-badblocks&#34;&gt;Check the health of a disk with badblocks.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The &lt;code&gt;badblocks&lt;/code&gt; command will write and read the disk with different patterns, thus overwriting the whole disk, so you will loose all the data in the disk.&lt;/p&gt; &lt;p&gt;This test is good for rotational disks as there is no disk degradation on massive writes, do not use it on SSD though.&lt;/p&gt; &lt;p&gt;WARNING: be sure that you specify the correct disk!!&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;badblocks&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-wsv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-b&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4096&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sde&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tee&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;disk_analysis_log.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If errors are shown is that all of the spare sectors of the disk are used, so you must not use this disk anymore. Again, check &lt;code&gt;dmesg&lt;/code&gt; for traces of disk errors.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubectl/kubectl_commands/#get-the-node-architecture-of-the-pods-of-a-deployment&#34;&gt;Get the node architecture of the pods of a deployment.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Here are a few ways to check the node architecture of pods in a deployment:&lt;/p&gt; &lt;ol&gt; &lt;li&gt; &lt;p&gt;Get the nodes where the pods are running: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pods&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;app&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your-deployment-label&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wide
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; This will show which nodes are running your pods.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Then check the architecture of those nodes: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;nodes&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;custom-columns&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;NAME:.metadata.name,ARCH:.status.nodeInfo.architecture
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ol&gt; &lt;p&gt;Or you can combine this into a single command: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pods&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;app&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your-deployment-label&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;json&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;jq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;.items[].spec.nodeName&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;xargs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-I&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;node&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;custom-columns&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;NAME:.metadata.name,ARCH:.status.nodeInfo.architecture
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;You can also check if your deployment is explicitly targeting specific architectures through node selectors or affinity rules: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;deployment&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;your-deployment-name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;yaml&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-A&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;nodeSelector
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#removing-a-disk-from-the-pool&#34;&gt;Removing a disk from the pool.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;remove&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank0&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sda
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This will trigger the data evacuation from the disk. Check &lt;code&gt;zpool status&lt;/code&gt; to see when it finishes.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#encrypting-zfs-drives-with-luks&#34;&gt;Encrypting ZFS Drives with LUKS.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Warning: Proceed with Extreme Caution&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;IMPORTANT SAFETY NOTICE:&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;These instructions will COMPLETELY WIPE the target drive&lt;/li&gt; &lt;li&gt;Do NOT attempt on production servers&lt;/li&gt; &lt;li&gt;Experiment only on drives with no valuable data&lt;/li&gt; &lt;li&gt;Seek professional help if anything is unclear&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;A drive you want to encrypt (will be referred to as &lt;code&gt;/dev/sdx&lt;/code&gt;)&lt;/li&gt; &lt;li&gt;Root access&lt;/li&gt; &lt;li&gt;Basic understanding of Linux command line&lt;/li&gt; &lt;li&gt;Backup of all important data&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Step 1: Create LUKS Encryption Layer&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;First, format the drive with LUKS encryption:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cryptsetup&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;luksFormat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;You&#39;ll be prompted for a sudo password&lt;/li&gt; &lt;li&gt;Create a strong encryption password (mix of uppercase, lowercase, numbers, symbols)&lt;/li&gt; &lt;li&gt;Note the precise capitalization in commands&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Step 2: Open the Encrypted Disk&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Open the newly encrypted disk:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cryptsetup&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;luksOpen&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdx&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sdx_crypt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This creates a mapped device at &lt;code&gt;/dev/mapper/sdx_crypt&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Step 3: Create ZFS Pool or the vdev&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;For example to create a ZFS pool on the encrypted device:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;create&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ashift&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;-O&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;compression&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;lz4&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
+&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/mapper/sdx_crypt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Check the &lt;a href=&#34;#create-your-pool&#34;&gt;create zpool section&lt;/a&gt; to know which configuration flags to use.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Step 4: Set Up Automatic Unlocking&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;Generate a Keyfile&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Create a random binary keyfile:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;bs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1024&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/dev/urandom&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;of&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/etc/zfs/keys/sdx.key
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;chmod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0400&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/zfs/keys/sdx.key
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;em&gt;Add Keyfile to LUKS&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Add the keyfile to the LUKS disk:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cryptsetup&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;luksAddKey&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdx&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/zfs/keys/sdx.key
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;You&#39;ll be asked to enter the original encryption password&lt;/li&gt; &lt;li&gt;This adds the binary file to the LUKS disk header&lt;/li&gt; &lt;li&gt;Now you can unlock the drive using either the password or the keyfile&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Step 5: Configure Automatic Mounting&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;Find Drive UUID&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Get the drive&#39;s UUID:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;blkid
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Look for the line with &lt;code&gt;TYPE=&#34;crypto_LUKS&#34;&lt;/code&gt;. Copy the UUID.&lt;/p&gt; &lt;p&gt;&lt;em&gt;Update Crypttab&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Edit the crypttab file:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;vim&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/crypttab
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Add an entry like:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sdx_crypt UUID=your-uuid-here /etc/zfs/keys/sdx.key luks,discard
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Final Step: Reboot&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Reboot your system&lt;/li&gt; &lt;li&gt;The drive will be automatically decrypted and imported&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;+- Keep your keyfile and encryption password secure - Store keyfiles with restricted permissions - Consider backing up the LUKS header&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Troubleshooting&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Double-check UUIDs&lt;/li&gt; &lt;li&gt;Verify keyfile permissions&lt;/li&gt; &lt;li&gt;Ensure cryptsetup and ZFS are installed&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Security Notes&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;This method provides full-disk encryption at rest&lt;/li&gt; &lt;li&gt;Data is inaccessible without the key or password&lt;/li&gt; &lt;li&gt;Protects against physical drive theft&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;While these instructions are comprehensive, they come with inherent risks. Always:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Have backups&lt;/li&gt; &lt;li&gt;Test in non-critical environments first&lt;/li&gt; &lt;li&gt;Understand each step before executing&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Further reading&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://wiki.alpinelinux.org/wiki/Setting_up_ZFS_on_LUKS&#34;&gt;Setting up ZFS on LUKS - Alpine Linux Wiki&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.malachisoord.com/2023/11/04/decrypt-additiona-luks-encrypted-volumes-on-boot/&#34;&gt;Decrypt Additional LUKS Encrypted Volumes on Boot&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://dradis.com/support/guides/customization/auto-unlock-luks-encrypted-drive.html&#34;&gt;Auto-Unlock LUKS Encrypted Drive - Dradis Support Guide&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://askubuntu.com/questions/996155/how-do-i-automatically-decrypt-an-encrypted-filesystem-on-the-next-reboot&#34;&gt;How do I automatically decrypt an encrypted filesystem on the next reboot? - Ask Ubuntu&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#add-a-disk-to-an-existing-vdev&#34;&gt;Add a disk to an existing vdev.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;add&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#add-a-vdev-to-an-existing-pool&#34;&gt;Add a vdev to an existing pool.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;``bash zpool add main raidz1-1 /dev/disk-1 /dev/disk-2 /dev/disk-3 /dev/disk-4 ```&lt;/p&gt; &lt;p&gt;You don&#39;t need to specify the &lt;code&gt;ashift&lt;/code&gt; or the &lt;code&gt;autoexpand&lt;/code&gt; as they are set on zpool creation.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#books&#34;&gt;Add zfs book.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://mwl.io/nonfiction/os#fmzfs&#34;&gt;FreeBSD Mastery: ZFS by Michael W Lucas and Allan Jude&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#replacing-a-disk-in-the-pool&#34;&gt;Replacing a disk in the pool.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;If the pool is not DEGRADED&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you want to do operations on your pool and want to prevent it from being DEGRADED you need to attach a new disk to the server and use the replace command&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;replace&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank0&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ata-WDC_WD2003FZEX-00SRLA0_WD-xxxxxxxxxxxx&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdX
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; Where &lt;code&gt;/dev/sdX&lt;/code&gt; is your temporal disk. Once the original disk is removed from the vdev you can do the operations you need.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#removing-a-disk-from-the-pool&#34;&gt;Removing a disk from the pool.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;remove&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank0&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sda
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This will trigger the data evacuation from the disk. Check &lt;code&gt;zpool status&lt;/code&gt; to see when it finishes.&lt;/p&gt; &lt;p&gt;Sometimes zfs won&#39;t allow you to remove a disk if it will put at risk the pool. In that case try to replace a disk in the pool as explained above.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#list-all-datasets-that-have-zfs-native-encryption-&#34;&gt;List all datasets that have zfs native encryption.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;```bash ROOT_FS=&#34;main&#34; is_encryption_enabled() { zfs get -H -o value encryption $1 | grep -q &#39;aes&#39; }&lt;/p&gt; &lt;p&gt;list_datasets_with_encryption() {&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# Initialize an array to hold dataset names
datasets=()

# List and iterate over all datasets starting from the root filesystem
for dataset in $(zfs list -H -o name | grep -E &#39;^&#39;$ROOT_FS&#39;/&#39;); do
    if is_encryption_enabled &#34;$dataset&#34;; then
        datasets+=(&#34;$dataset&#34;)
    fi
done

# Output the results
echo &#34;ZFS datasets with encryption enabled:&#34;
printf &#39;%s\n&#39; &#34;${datasets[@]}&#34;
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;list_datasets_with_encryption&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#cannot-destroy-dataset:-dataset-is-busy&#34;&gt;Troubleshoot cannot destroy dataset: dataset is busy.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you&#39;re experiencing this error and can reproduce the next traces:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cannot&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;destroy&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;zroot/2013-10-15T065955229209&#39;&lt;/span&gt;:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dataset&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;is&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;busy

cannot&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;unmount&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;zroot/2013-10-15T065955229209&#39;&lt;/span&gt;:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;not&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;currently&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mounted

zroot/2013-10-15T065955229209&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;.86G&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;25&lt;/span&gt;.0G&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;.0G&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;/var/lib/heaver/instances/2013-10-15T065955229209

umount:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/heaver/instances/2013-10-15T065955229209:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;not&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mounted
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can &lt;code&gt;grep zroot/2013-10-15T065955229209 /proc/*/mounts&lt;/code&gt; to see which process is still using the dataset.&lt;/p&gt; &lt;p&gt;Another possible culprit are snapshots, you can then run:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;holds&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$snapshotname&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To see if it has any holds, and if so, &lt;code&gt;zfs release&lt;/code&gt; to remove the hold.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#upgrading-zfs-storage-pools&#34;&gt;Upgrading ZFS Storage Pools.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you have ZFS storage pools from a previous zfs release you can upgrade your pools with the &lt;code&gt;zpool upgrade&lt;/code&gt; command to take advantage of the pool features in the current release. In addition, the zpool status command has been modified to notify you when your pools are running older versions. For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;status

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;pool:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;state:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ONLINE
status:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;The&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;is&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;formatted&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;using&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;an&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;older&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;on-disk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;format.&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;The&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;can
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;still&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;be&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;used,&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;but&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;some&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;features&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;are&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;unavailable.
action:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Upgrade&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;the&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;using&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;zpool upgrade&#39;&lt;/span&gt;.&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Once&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;this&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;is&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;,&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;the
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;pool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;will&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;no&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;longer&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;be&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;accessible&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;on&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;older&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;software&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;versions.
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;scrub:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;none&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;requested
config:
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;NAME&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;STATE&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;READ&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;WRITE&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;CKSUM
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;tank&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;mirror-0&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;c1t0d0&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;c1t1d0&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
errors:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;No&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;known&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;data&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;errors
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can use the following syntax to identify additional information about a particular version and supported releases:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;upgrade&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v

This&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;system&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;is&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;currently&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;running&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ZFS&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;version&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;22&lt;/span&gt;.

The&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;following&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;versions&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;are&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;supported:

VER&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;DESCRIPTION
---&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;--------------------------------------------------------
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;Initial&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ZFS&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;version
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;Ditto&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;blocks&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;replicated&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;metadata&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;Hot&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;spares&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;and&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;double&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;parity&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;RAID-Z
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;history&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;Compression&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;using&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;the&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;gzip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;algorithm
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;bootfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;property
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;Separate&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;intent&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;devices
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;Delegated&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;administration
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;9&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;refquota&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;and&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;refreservation&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;properties
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Cache&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;devices
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Improved&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;scrub&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;performance
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Snapshot&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;properties
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;13&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;snapused&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;property
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;passthrough-x&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;aclinherit
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;user/group&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;space&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;accounting
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;16&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;stmf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;property&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;support
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;17&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Triple-parity&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;RAID-Z
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;18&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Snapshot&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;user&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;holds
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;19&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;device&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;removal
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Compression&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;using&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zle&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;zero-length&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;encoding&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Reserved
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;22&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Received&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;properties

For&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;more&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;information&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;on&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;particular&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;version,&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;including&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;supported&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;releases,
see&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;the&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ZFS&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Administration&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Guide.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then, you can run the zpool upgrade command to upgrade all of your pools. For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;upgrade&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-a
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#monitor-the-zfs-ram-usage&#34;&gt;Monitor the zfs ram usage.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;HostOutOfMemory&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# if we don&#39;t add the node_zfs_arc_size, the ARC is taken as used space triggering the alert as a false positive&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;(node_memory_MemAvailable_bytes + node_zfs_arc_size)/ node_memory_MemTotal_bytes * 100 &amp;lt; 10&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;5m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Host out of memory (instance {{ $labels.instance }})&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;Node&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;memory&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;filling&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;up&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(&amp;lt;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;10%&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;left)\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;\ }}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; feat(linux_snippets#Unattended upgrades): Unattended upgrades&lt;/p&gt; &lt;p&gt;unattended-upgrades runs daily at a random time&lt;/p&gt; &lt;p&gt;&lt;strong&gt;How to tell when unattended upgrades will run today:&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The random time is set by a cron job (/etc/cron.daily/apt.compat), and you can read the random time for today by asking systemd:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list-timers&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-daily.timer
NEXT&lt;span class=&#34;w&#34;&gt;                         &lt;/span&gt;LEFT&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;LAST&lt;span class=&#34;w&#34;&gt;                         &lt;/span&gt;PASSED&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;UNIT&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;ACTIVATES
Tue&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2017&lt;/span&gt;-07-11&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;01&lt;/span&gt;:53:29&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;CDT&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;13h&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;left&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Mon&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2017&lt;/span&gt;-07-10&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:22:40&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;CDT&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;1h&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;9min&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ago&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-daily.timer&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-daily.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;In this case, you can see that it ran 1 hour and 9 minutes ago.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;How to tell if unattended upgrades are still running:&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;One easy way is to check the timestamp files for the various apt components:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ls&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/apt/periodic/
total&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
-rw-r--r--&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;root&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;root&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Jul&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:24&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;unattended-upgrades-stamp
-rw-r--r--&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;root&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;root&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Jul&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:23&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update-stamp
-rw-r--r--&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;root&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;root&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Jul&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:24&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update-success-stamp
-rw-r--r--&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;root&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;root&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Jul&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:24&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;upgrade-stamp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Putting the data together, you can see that the timer started apt at 11:22. It ran an update which completed at 11:23, then an upgrade which completed at 11:24. Finally, you can see that apt considered the upgrade to be a success (no error or other failure).&lt;/p&gt; &lt;p&gt;Obviously, if you see a recent timer without a corresponding completion timestamp, then you might want to check ps to see if apt is still running.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;How to tell which step apt is running right now&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;One easy way is to check the logfile.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;less&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/log/unattended-upgrades/unattended-upgrades.log
&lt;span class=&#34;m&#34;&gt;2017&lt;/span&gt;-07-10&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:23:00,348&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;INFO&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Initial&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;blacklisted&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;packages:
&lt;span class=&#34;m&#34;&gt;2017&lt;/span&gt;-07-10&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:23:00,349&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;INFO&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Initial&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;whitelisted&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;packages:
&lt;span class=&#34;m&#34;&gt;2017&lt;/span&gt;-07-10&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:23:00,349&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;INFO&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Starting&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;unattended&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;upgrades&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;script
&lt;span class=&#34;m&#34;&gt;2017&lt;/span&gt;-07-10&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:23:00,349&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;INFO&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Allowed&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;origins&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;are:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;o=Ubuntu,a=zesty-security&#39;&lt;/span&gt;,&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;o=Ubuntu,a=zesty-updates&#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;m&#34;&gt;2017&lt;/span&gt;-07-10&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:23:10,485&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;INFO&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Packages&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;that&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;will&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;be&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;upgraded:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apport&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apport-gtk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libpoppler-glib8&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libpoppler-qt5-1&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libpoppler64&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;poppler-utils&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;python3-apport&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;python3-problem-report
&lt;span class=&#34;m&#34;&gt;2017&lt;/span&gt;-07-10&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:23:10,485&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;INFO&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Writing&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dpkg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;to&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;/var/log/unattended-upgrades/unattended-upgrades-dpkg.log&#39;&lt;/span&gt;
&lt;span class=&#34;m&#34;&gt;2017&lt;/span&gt;-07-10&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:24:20,419&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;INFO&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;All&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;upgrades&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;installed
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Here you can see the normal daily process, including the &#39;started&#39; and &#39;completed&#39; lines, and the list of packages that were about to be upgraded.&lt;/p&gt; &lt;p&gt;If the list of packages is not logged yet, then apt can be safely interrupted. Once the list of packages is logged, DO NOT interrupt apt.&lt;/p&gt; &lt;p&gt;**Check the number of packages that need an upgrade **&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;apt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--upgradeable
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; **Manually run the unattended upgrades **&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;unattended-upgrade&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;unison&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/unison/&#34;&gt;unison&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/unison/#installation&#34;&gt;Installation.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you are on debian or ubuntu, the version of the repositories &lt;a href=&#34;https://github.com/bcpierce00/unison/issues/208&#34;&gt;does not allow you to run the program with the file watcher&lt;/a&gt;, so you may need to build it yourself:&lt;/p&gt; &lt;p&gt;First install the dependencies:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ocaml-native-compilers
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;UNISON_VERSION&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;.53.8
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Install Unison.&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;pushd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/tmp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wget&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://github.com/bcpierce00/unison/archive/v&lt;span class=&#34;nv&#34;&gt;$UNISON_VERSION&lt;/span&gt;.tar.gz&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tar&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-xzvf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;v&lt;span class=&#34;nv&#34;&gt;$UNISON_VERSION&lt;/span&gt;.tar.gz&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;v&lt;span class=&#34;nv&#34;&gt;$UNISON_VERSION&lt;/span&gt;.tar.gz&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;pushd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;unison-&lt;span class=&#34;nv&#34;&gt;$UNISON_VERSION&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;make&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/usr/local/bin&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;./src/unison&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;./src/unison-fsmonitor&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;popd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-rf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;unison-&lt;span class=&#34;nv&#34;&gt;$UNISON_VERSION&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;popd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then remove the ocaml compilers as they take quite some space:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;remove&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ocaml-native-compilers
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/unison/#run-in-the-background-watching-changes&#34;&gt;Run in the background watching changes.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Create the systemd service in: &lt;code&gt;~/.config/systemd/user/unison.service&lt;/code&gt; (assuming that your profile is orgfiles)&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[Unit]
Description=unison

[Service]
ExecStart=/usr/local/bin/unison orgfiles
Restart=on-failure
RestartSec=3

[Install]
WantedBy=default.target
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;renovate&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/nix/&#34;&gt;renovate&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add mention to sixos.&lt;/p&gt; &lt;p&gt;Think about using &lt;a href=&#34;https://media.ccc.de/v/38c3-sixos-a-nix-os-without-systemd&#34;&gt;sixos&lt;/a&gt; instead, a nixos without systemd&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/renovate/#installation&#34;&gt;Installation in gitea actions.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Create Renovate Bot Account and generate a token for the Gitea Action secret&lt;/li&gt; &lt;li&gt;Add the renovate bot account as collaborator with write permissions to the repository you want to update.&lt;/li&gt; &lt;li&gt;Create a repository to store our Renovate bot configurations, assuming called renovate-config.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;In renovate-config, create a file config.js to configure Renovate:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;err&#34;&gt;module.expor&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;ts&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;endpoint&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;https://gitea.com/api/v1&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// replace it with your actual endpoint&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;gitAuthor&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Renovate Bot &amp;lt;renovate-bot@yourhost.com&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;platform&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;gitea&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;onboardingConfigFileName&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;renovate.json&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;autodiscover&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;optimizeForDisabled&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you&#39;re using mysql or you see errors like &lt;code&gt;.../repository/pulls 500 internal error&lt;/code&gt; you &lt;a href=&#34;https://github.com/renovatebot/renovate/issues/10264&#34;&gt;may need to set &lt;code&gt;unicodeEmoji: false&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/renovate/#configuration&#34;&gt;Configure renovate.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://docs.renovatebot.com/configuration-options/#automerge&#34;&gt;automerge&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;By default, Renovate raises PRs but leaves them to someone or something else to merge them. By configuring this setting, you allow Renovate to automerge PRs or even branches. Using automerge reduces the amount of human intervention required.&lt;/p&gt; &lt;p&gt;Usually you won&#39;t want to automerge all PRs, for example most people would want to leave major dependency updates to a human to review first. You could configure Renovate to automerge all but major this way:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;packageRules&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;matchUpdateTypes&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;minor&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;patch&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;pin&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;digest&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;automerge&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Also note that this option can be combined with other nested settings, such as dependency type. So for example you could choose to automerge all (passing) devDependencies only this way:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;packageRules&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;matchDepTypes&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;devDependencies&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;automerge&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Configure docker version extraction&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/renovatebot/renovate/discussions/18190&#34;&gt;Ansible Manager Docker-type dependency extraction · renovatebot/renovate · Discussion #18190 · GitHub&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://docs.renovatebot.com/modules/manager/ansible/&#34;&gt;Automated Dependency Updates for Ansible - Renovate Docs&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/renovatebot/renovate/issues/3720&#34;&gt;Pin packages in ansible roles · Issue #3720 · renovatebot/renovate&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/renovatebot/renovate/issues/4635&#34;&gt;Support default environment variable values in docker-compose · Issue #4635 · renovatebot/renovate&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/renovatebot/renovate/issues/31685&#34;&gt;Support docker-compose.yml versions from .env files · Issue #31685 · renovatebot/renovate&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Combine all updates to one branch/PR&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://docs.renovatebot.com/presets-group/#groupallnonmajor&#34;&gt;Group Presets - Renovate Docs group all non major&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://docs.renovatebot.com/presets-group/#groupall&#34;&gt;Group Presets - Renovate Docs group all&lt;/a&gt;&lt;/li&gt; &lt;li&gt; &lt;h3 id=&#34;config-renovate-combine-all-updates-to-one-branchpr-stack-overflow&#34;&gt;&lt;a href=&#34;https://stackoverflow.com/questions/66471226/renovate-combine-all-updates-to-one-branch-pr&#34;&gt;config - Renovate: Combine all updates to one branch/PR - Stack Overflow&lt;/a&gt;&lt;/h3&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/renovate/#references&#34;&gt;Add upgrade notes.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://docs.renovatebot.com/release-notes-for-major-versions/&#34;&gt;Upgrade notes&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;debugging&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/kubernetes_debugging/&#34;&gt;Debugging&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/kubernetes_debugging/#pvc-or-pv-is-stuck-deleting&#34;&gt;PVC or PV is stuck deleting.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;When PVs and PVCs get stuck during deletion, it&#39;s usually due to finalizers that prevent the cleanup process from completing. Here are several approaches to resolve this:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Check for Finalizers&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;First, examine what&#39;s preventing the deletion:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;pv-name&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;yaml&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;finalizers&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-A&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;5&lt;/span&gt;
kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pvc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;pvc-name&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;namespace&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;yaml&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;finalizers&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-A&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Remove Finalizers (Most Common Solution)&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you see finalizers like &lt;code&gt;kubernetes.io/pv-protection&lt;/code&gt; or &lt;code&gt;kubernetes.io/pvc-protection&lt;/code&gt;, you can remove them:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;patch&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pvc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;pvc-name&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;namespace&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;{&#34;metadata&#34;:{&#34;finalizers&#34;:null}}&#39;&lt;/span&gt;

kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;patch&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;pv-name&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;{&#34;metadata&#34;:{&#34;finalizers&#34;:null}}&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;node-exporter&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/node_exporter/&#34;&gt;Node Exporter&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/node_exporter/#host-requires-a-reboot&#34;&gt;Monitor host requires a reboot.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Node exporter &lt;a href=&#34;https://github.com/prometheus/node_exporter/issues/625&#34;&gt;does not support this metric&lt;/a&gt;, but you can monitor reboot requirements using Prometheus node exporter&#39;s textfile collector. Here&#39;s how to set it up:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Create the monitoring script&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;First, create a script that checks for the reboot-required file and outputs metrics in Prometheus format:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Make the script executable and place it in the right location:&lt;/strong&gt;&lt;/li&gt; &lt;/ol&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reboot-required-check.sh&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/usr/local/bin/
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;chmod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;+x&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/usr/local/bin/reboot-required-check.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;TEXTFILE_DIR&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;/var/lib/node_exporter/textfile_collector&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;METRIC_FILE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TEXTFILE_DIR&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/reboot_required.prom&#34;&lt;/span&gt;

mkdir&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TEXTFILE_DIR&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/run/reboot-required&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;REBOOT_REQUIRED&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;REBOOT_REQUIRED&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$METRIC_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;lt;&amp;lt; EOF&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;node_reboot_required $REBOOT_REQUIRED&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;EOF&lt;/span&gt;

chmod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;644&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$METRIC_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Ensure the textfile collector directory exists:&lt;/strong&gt;&lt;/li&gt; &lt;/ol&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mkdir&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/node_exporter/textfile_collector
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;chown&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;node_exporter:node_exporter&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/node_exporter/textfile_collector
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Create a systemd service to run the script periodically:&lt;/strong&gt;&lt;/li&gt; &lt;/ol&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[Unit]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Check if system requires reboot&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;After&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;network.target&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Service]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;oneshot&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;ExecStart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/usr/local/bin/reboot-required-check.sh&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;User&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;node_exporter&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Group&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;node_exporter&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Install]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;WantedBy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;multi-user.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Create a systemd timer to run it regularly:&lt;/strong&gt;&lt;/li&gt; &lt;/ol&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[Unit]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Check if system requires reboot every 5 minutes&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Requires&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;reboot-check.service&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Timer]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;OnBootSec&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;1min&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;OnUnitActiveSec&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;5min&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Install]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;WantedBy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;timers.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Install and enable the systemd units:&lt;/strong&gt;&lt;/li&gt; &lt;/ol&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reboot-check.service&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/systemd/system/
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reboot-check.timer&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/systemd/system/
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;daemon-reload
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;enable&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reboot-check.timer
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;start&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reboot-check.timer
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Configure node exporter to use the textfile collector:&lt;/strong&gt; Make sure your node exporter is started with the &lt;code&gt;--collector.textfile.directory&lt;/code&gt; flag:&lt;/li&gt; &lt;/ol&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;node_exporter&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--collector.textfile.directory&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/var/lib/node_exporter/textfile_collector
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Prometheus alerting rule&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can create an alerting rule in Prometheus to notify when a reboot is required:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;groups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;system.rules&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;SystemRebootRequired&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;node_reboot_required == 1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;System&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;requires&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;reboot&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;System&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;requires&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;reboot&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;due&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;to:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.reason&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Testing&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can test the setup by:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Run the script manually:&lt;/strong&gt;&lt;/li&gt; &lt;/ol&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/usr/local/bin/reboot-required-check.sh
cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/node_exporter/textfile_collector/reboot_required.prom
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Check if the timer is working:&lt;/strong&gt;&lt;/li&gt; &lt;/ol&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;status&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reboot-check.timer
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;journalctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-u&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reboot-check.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Verify metrics are being collected:&lt;/strong&gt; Visit &lt;code&gt;http://your-server:9100/metrics&lt;/code&gt; and search for &lt;code&gt;node_reboot_required&lt;/code&gt;&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;The metrics will show &lt;code&gt;node_reboot_required 1&lt;/code&gt; when a reboot is required and &lt;code&gt;node_reboot_required 0&lt;/code&gt; when it&#39;s not. The &lt;code&gt;node_reboot_required_packages_info&lt;/code&gt; metric includes information about which packages triggered the reboot requirement.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;operating-systems&#34;&gt;Operating Systems&lt;/h3&gt; &lt;h4 id=&#34;dunst&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/dunst/&#34;&gt;dunst&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Tweak installation steps.&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libdbus-1-dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libx11-dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libxinerama-dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libxrandr-dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libxss-dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libglib2.0-dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;libpango1.0-dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libgtk-3-dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libxdg-basedir-dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libgdk-pixbuf-2.0-dev

make&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;WAYLAND&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;make&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;WAYLAND&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; If it didn&#39;t create the systemd service you can &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#create-a-systemd-service-for-a-non-root-user&#34;&gt;create it yourself&lt;/a&gt; with this service file&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[Unit]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Dunst notification daemon&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Documentation&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;man:dunst(1)&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;PartOf&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;graphical-session.target&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Service]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;dbus&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;BusName&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;org.freedesktop.Notifications&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;ExecStart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/usr/local/bin/dunst&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Slice&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;session.slice&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Environment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;PATH=%h/.local/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Install]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;WantedBy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;default.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You may need to add more paths to PATH.&lt;/p&gt; &lt;p&gt;To see the logs of the service use &lt;code&gt;journalctl --user -u dunst.service -f --since &#34;15 minutes ago&#34;&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/dunst/#configuration&#34;&gt;Configuration.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Read and tweak the &lt;code&gt;~/.dunst/dunstrc&lt;/code&gt; file to your liking. You have the &lt;a href=&#34;https://github.com/dunst-project/dunst/blob/master/dunstrc&#34;&gt;default one here&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You&#39;ll also need to configure the actions in your window manager. In my case &lt;a href=&#34;https://lyz-code.github.io/blue-book/i3wm/&#34;&gt;i3wm&lt;/a&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;bindsym $mod+b exec dunstctl close-all
bindsym $mod+v exec dunstctl context
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/dunst/#configure-each-application-notification&#34;&gt;Configure each application notification.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can look at &lt;a href=&#34;https://gist.github.com/rosoau/fdfa7b3e37e3c5c67b7dad1b7257236e&#34;&gt;rosoau config&lt;/a&gt; for inspiration&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt; * &lt;a href=&#34;https://github.com/dunst-project/dunst/issues/826&#34;&gt;Some dunst configs&lt;/a&gt; * Smarttech101 tutorials (&lt;a href=&#34;https://smarttech101.com/how-to-configure-dunst-notifications-in-linux-with-images&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;https://smarttech101.com/how-to-send-notifications-in-linux-using-dunstify-notify-send#Taking_Actions_on_notifications_using_dunstifynotify-send&#34;&gt;2&lt;/a&gt;) * &lt;a href=&#34;https://wiki.archlinux.org/title/Dunst&#34;&gt;Archwiki page on dunst&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;linux-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/simplexchat/&#34;&gt;Linux Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#prevent-the-screen-from-turning-off&#34;&gt;Prevent the screen from turning off.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;VESA Display Power Management Signaling (DPMS) enables power saving behaviour of monitors when the computer is not in use. The time of inactivity before the monitor enters into a given saving power level—standby, suspend or off—can be set as described in DPMSSetTimeouts(3).&lt;/p&gt; &lt;p&gt;It is possible to turn off your monitor with the xset command&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;xset&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;off&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-dpms
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; It will disable DPMS and prevent screen from blanking&lt;/p&gt; &lt;p&gt;To query the current settings:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;xset&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;q
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If that doesn&#39;t work you can use the &lt;a href=&#34;https://github.com/carrot69/keep-presence/&#34;&gt;keep-presence&lt;/a&gt; program&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;keep-presence
keep-presence&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-c
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;That will move the cursor one pixel in circles each 300s, if you need to move it more often use the &lt;code&gt;-s&lt;/code&gt; flag.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#protect-the-edition-of-a-pdf-with-a-password&#34;&gt;Protect the edition of a pdf with a password.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use &lt;code&gt;pdftk&lt;/code&gt;. From its man page:&lt;/p&gt; &lt;p&gt;Encrypt a PDF using 128-Bit Strength (the Default) and Withhold All Permissions (the Default)&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pdftk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mydoc&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;.pdf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mydoc.128&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;.pdf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;owner_pw&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;foopass&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Same as Above, Except a Password is Required to Open the PDF&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pdftk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mydoc&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;.pdf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mydoc.128&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;.pdf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;owner_pw&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;foo&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;user_pw&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;baz&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Same as Above, Except Printing is Allowed (after the PDF is Open)&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pdftk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mydoc&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;.pdf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mydoc.128&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;.pdf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;owner_pw&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;foo&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;user_pw&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;baz&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;allow&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pri
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To check if it has set the password correctly you &lt;a href=&#34;https://stackoverflow.com/questions/4039659/is-it-possible-to-check-if-pdf-is-password-protected-using-ghostscript&#34;&gt;can run&lt;/a&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pdftk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;input.pdf&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dump_data&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dont_ask
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#reduce-the-size-of-an-image&#34;&gt;Reduce the size of an image.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The simplest way of reducing the size of the image is by degrading the quality of the image.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;convert&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;INPUT_FILE&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-quality&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;50&lt;/span&gt;%&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;OUTPUT_FILE&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The main difference between &lt;code&gt;convert&lt;/code&gt; and &lt;code&gt;mogrify&lt;/code&gt; command is that &lt;code&gt;mogrify&lt;/code&gt; command applies the operations on the original image file, whereas convert does not.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mogrify&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-quality&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;50&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;*.jpg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#change-the-default-shell-of-a-user-using-the-command-line&#34;&gt;Change the default shell of a user using the command line.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;chsh&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/usr/bin/zsh&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;lyz
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce simplex chat.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://simplex.chat/&#34;&gt;Simplex chat&lt;/a&gt; is the first messenger without user IDs&lt;/p&gt; &lt;p&gt;I went to a talk in the &lt;a href=&#34;https://lyz-code.github.io/blue-book/ccc/&#34;&gt;38c3&lt;/a&gt; (december 2024), and even though the project looked good there were some stuff that pushed me away:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The cypher has not been tested&lt;/li&gt; &lt;li&gt;It&#39;s not fully open sourced&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#record-the-audio-from-your-computer&#34;&gt;Record the audio from your computer.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can record audio being played in a browser using &lt;code&gt;ffmpeg&lt;/code&gt;&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Check your default audio source:&lt;/li&gt; &lt;/ol&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pactl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sources&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-E&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Name|Description&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt;Record using &lt;code&gt;ffmpeg&lt;/code&gt;:&lt;/li&gt; &lt;/ol&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ffmpeg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pulse&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;your_monitor_source&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output.wav
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ffmpeg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pulse&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;alsa_output.pci-0000_00_1b.0.analog-stereo.monitor&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output.wav
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt;Stop recording with &lt;strong&gt;Ctrl+C&lt;/strong&gt;.&lt;/li&gt; &lt;/ol&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#download-videos-from-rtve.es&#34;&gt;Download videos from rtve.es.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use &lt;a href=&#34;https://www.descargavideos.tv/&#34;&gt;descargavideos.tv&lt;/a&gt; (&lt;a href=&#34;https://github.com/forestrf/Descargavideos&#34;&gt;source&lt;/a&gt;)&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#check-if-a-domain-is-in-a-list-of-known-disposable-email-domains&#34;&gt;Check if a domain is in a list of known disposable email domains.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can check in known lists &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;wget&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://raw.githubusercontent.com/andreis/disposable-email-domains/master/domains.txt
grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;homapin.com&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;domains.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;Or using web services that either use the IPs (obtained by whois/dig)&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;https://www.blocklist.de/en/search.html?ip=142.132.166.12&amp;amp;action=search&amp;amp;send=start+search 👍
https://www.blocklist.de/en/search.html?ip=188.166.111.252&amp;amp;action=search&amp;amp;send=start+search 👍
https://www.blocklist.de/en/search.html?ip=46.101.111.206&amp;amp;action=search&amp;amp;send=start+search 👍
https://www.blocklist.de/en/search.html?ip=116.202.9.167&amp;amp;action=search&amp;amp;send=start+search 👍
https://check.spamhaus.org/results/?query=homapin.com 👍
https://verifymail.io/domain/homapin.com 👎
https://www.ipqualityscore.com/domain-reputation/homapin.com 👎
https://quickemailverification.com/tools/disposable-email-address-detector for
  - homapin.com 👎
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#mount-a-cdrom-or-dvd&#34;&gt;Mount a cdrom or dvd.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;TL;DR: The syntax is as follows for the mount command:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mount&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;iso9660&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ro&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/deviceName&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/path/to/mount/point
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Use the following command to find out the name Of DVD / CD-ROM / Writer / Blu-ray device on a Linux based system:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;lsblk
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;OR use the combination of the dmesg command and grep/egrep as follow to print your CD/DVD device name. For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;dmesg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-E&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--color&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;cdrom|dvd|cd/rw|writer&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Sample outputs indicating that the /dev/sr0 is my device name:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[    5.437164] sr0: scsi3-mmc drive: 24x/24x writer dvd-ram cd/rw xa/form2 cdda tray
[    5.437307] cdrom: Uniform CD-ROM driver Revision: 3.20
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Create a mount point, type mkdir command as follows:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mkdir&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/mnt/cdrom
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Mount the /dev/cdrom or /dev/sr0 as follows:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mount&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;iso9660&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ro&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/cdrom&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/mnt/cdrom
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#use-lftp&#34;&gt;Use lftp.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Connect with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;lftp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;port&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;user@host
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Navigate with &lt;code&gt;ls&lt;/code&gt; and &lt;code&gt;cd&lt;/code&gt;. Get with &lt;code&gt;mget&lt;/code&gt; for multiple things&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#difference-between-apt-get-upgrate-and-apt-get-full-upgrade&#34;&gt;Difference between apt-get upgrate and apt-get full-upgrade.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The difference between &lt;code&gt;upgrade&lt;/code&gt; and &lt;code&gt;full-upgrade&lt;/code&gt; is that the later will remove the installed packages if that is needed to upgrade the whole system. Be extra careful when using this command&lt;/p&gt; &lt;p&gt;I will more frequently use &lt;code&gt;autoremove&lt;/code&gt; to remove old packages and then just use &lt;code&gt;upgrade&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#upgrade-debian&#34;&gt;Upgrade debian.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;upgrade
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;full-upgrade

sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;vi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/apt/sources.list&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/apt/sources.list.d/*

sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;clean
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update

sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;upgrade
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;full-upgrade

sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;autoremove

sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;shutdown&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;now
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#get-a-list-of-extensions-by-file-type&#34;&gt;Get a list of extensions by file type.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;There are community made lists such as &lt;a href=&#34;https://github.com/dyne/file-extension-list/&#34;&gt;dyne&#39;s file extension list&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#upgrade-ubuntu&#34;&gt;Upgrade ubuntu.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Upgrade your system:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;upgrade
reboot
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You must install ubuntu-release-upgrader-core package:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ubuntu-release-upgrader-core
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Ensure the Prompt line in &lt;code&gt;/etc/update-manager/release-upgrades&lt;/code&gt; is set to ‘lts‘ using the “grep” or “cat”&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;lts&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/update-manager/release-upgrades
cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/update-manager/release-upgrades
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Opening up TCP port 1022&lt;/p&gt; &lt;p&gt;For those using ssh-based sessions, open an additional SSH port using the ufw command, starting at port 1022. This is the default port set by the upgrade procedure as a fallback if the default SSH port dies during upgrades.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/sbin/iptables&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-I&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;INPUT&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tcp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--dport&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1022&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-j&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ACCEPT
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Finally, start the upgrade from Ubuntu 22.04 to 24.04 LTS version. Type:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;-release-upgrade&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#check-the-file-encoding&#34;&gt;Check the file encoding.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;file&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;path_to_file&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#simulate-the-environment-of-a-cron-job&#34;&gt;Simulate the environment of a cron job.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Add this to your crontab (temporarily):&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;* * * * * env &amp;gt; ~/cronenv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;After it runs, do this:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;env&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;~/cronenv&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/bin/sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This assumes that your cron runs /bin/sh, which is the default regardless of the user&#39;s default shell.&lt;/p&gt; &lt;p&gt;Footnote: if env contains more advanced config, eg &lt;code&gt;PS1=$(__git_ps1 &#34; (%s)&#34;)$&lt;/code&gt;, it will error cryptically &lt;code&gt;env: &#34;: No such file or directory&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#resize-a-partition-of-an-ec2-instance&#34;&gt;Resize a partition of an EC2 instance.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If it&#39;s the first partition of the first disk.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;growpart&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/nvme0n1&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
resize2fs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/nvme0n1p1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#debugging-inotify-watch-exhaustion:-&#34; title=&#34;no-space-left-on-device&#34;&gt;Debugging Inotify Watch Exhaustion: &#34;No space left on device&#34;.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you get &lt;code&gt;No space left on device&lt;/code&gt; errors in systemd logs, but disk space is fine:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;systemd[755863]: my-service.service: Failed to add control inotify watch descriptor for control group: No space left on device
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This is actually an &lt;strong&gt;inotify watches exhaustion&lt;/strong&gt; issue, not disk space.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Diagnosis&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Check Current Limits&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/sys/fs/inotify/max_user_watches
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Count Current Watch Usage&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;find&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/*/fdinfo/*&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-exec&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;^inotify&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;awk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;{sum+=$1} END {print sum}&#39;&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pid&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;ps&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-eo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pid&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--no-headers&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;/fd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;total&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;fd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;/fd/*&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-L&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$fd&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;readlink&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$fd&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-q&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;anon_inotify&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fdnum&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;basename&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$fd&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;watches&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;^inotify&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;/fdinfo/&lt;span class=&#34;nv&#34;&gt;$fdnum&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;total&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;total&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;watches&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$total&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-gt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;ps&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;comm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--no-headers&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;unknown&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$total&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$cmd&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sort&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-nr&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;head&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-10
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Find High File Descriptor Processes&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Often the culprits have many open files:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pid&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;ps&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-eo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pid&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--no-headers&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;/fd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fd_count&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;ls&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;/fd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$fd_count&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-gt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;ps&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;comm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--no-headers&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$fd_count&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; FDs: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$cmd&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Common Culprits&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Media servers&lt;/strong&gt;: Jellyfin, Plex&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Download managers&lt;/strong&gt;: Sonarr, Radarr, Lidarr&lt;/li&gt; &lt;li&gt;&lt;strong&gt;File sync&lt;/strong&gt;: Syncthing, Nextcloud&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Development tools&lt;/strong&gt;: IDEs, file watchers&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Container platforms&lt;/strong&gt;: Docker, containerd&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;1. Increase Limits (Quick Fix)&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;500000&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/sys/fs/inotify/max_user_watches

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;fs.inotify.max_user_watches=500000&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/sysctl.conf
sysctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Memory cost&lt;/strong&gt;: ~540 bytes per watch (500k watches ≈ 270MB kernel memory)&lt;/p&gt; &lt;p&gt;&lt;strong&gt;2. Configure Applications&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Better long-term solution:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Sonarr/Radarr/Lidarr&lt;/strong&gt;:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Settings → Media Management → Disable &#34;Scan for changes&#34;&lt;/li&gt; &lt;li&gt;Use scheduled scans instead&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Jellyfin&lt;/strong&gt;:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Admin → Dashboard → Libraries → Disable real-time monitoring&lt;/li&gt; &lt;li&gt;Use periodic library scans&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Syncthing&lt;/strong&gt;:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Use polling instead of inotify for large directories&lt;/li&gt; &lt;li&gt;Add &lt;code&gt;.stignore&lt;/code&gt; for unnecessary paths&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#manage-bluetooth&#34;&gt;Manage bluetooth.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;List devices&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Once you&#39;ve paired your devices you can see them with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;bluetoothctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;devices
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To check the ones that are connected use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;bluetoothctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;devices&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Connected
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Connect device&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;From the list above you will see the device ID, then you can:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;bluetoothctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;connect&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;device_ID
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;But it&#39;s better to use &lt;code&gt;blueman-manager&lt;/code&gt; because it handles better the connections and disconnections&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Multidevice connection&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Sometimes the laptop is not able to send the audio streams back to the connected device. Restart the controlling device with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--user&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;restart&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wireplumber.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#bluetooth-pairing-troubleshooting:-when-ble-devices-won&#39;t-connect&#34;&gt;Bluetooth Pairing Troubleshooting: When BLE Devices Won&#39;t Connect.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Bluetooth Low Energy (BLE) devices like wireless earbuds appear in device scans but fail to pair with &#34;Device not available&#34; errors, even though they&#39;re visible to other devices.&lt;/p&gt; &lt;p&gt;The root ’cause may be that the HCI controller corruption causing discovery operations to fail. The Bluetooth hardware gets stuck in a state where it rejects pairing attempts with error code -16 (EBUSY).&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;hcitool lescan&lt;/code&gt; shows the device&lt;/li&gt; &lt;li&gt;&lt;code&gt;bluetoothctl&lt;/code&gt; scan shows device briefly or not at all&lt;/li&gt; &lt;li&gt;&lt;code&gt;bluetoothctl pair [MAC]&lt;/code&gt; returns &#34;Device not available&#34;&lt;/li&gt; &lt;li&gt;&lt;code&gt;dmesg&lt;/code&gt; shows HCI opcode failures like: &lt;code&gt;Bluetooth: hci0: Opcode 0x0401 failed: -16&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Complete Bluetooth stack reset:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;stop&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;bluetooth

sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rmmod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;btusb

sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;modprobe&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;btusb

sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;start&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;bluetooth
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If that doesn&#39;t work. Try forcing bluetoothctl to see LE devices specifically:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;bluetoothctl&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# this will open the bluetooth cli&lt;/span&gt;
menu&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;scan
clear
transport&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;le
back
scan&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;on
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#how-to-increase-touchpad-sensitivity-on-linux&#34;&gt;How to Increase Touchpad Sensitivity on Linux.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Adjust touchpad sensitivity settings for better responsiveness and control on Linux systems.&lt;/p&gt; &lt;p&gt;First, identify your touchpad device:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;xinput&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Check current properties:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;xinput&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list-props&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Synaptics TM3381-002&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Increase pointer sensitivity (range: -1.0 to 1.0):&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;xinput&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;set-prop&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Synaptics TM3381-002&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;libinput Accel Speed&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Make scrolling more sensitive:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;xinput&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;set-prop&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Synaptics TM3381-002&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;libinput Scrolling Pixel Distance&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Once you have the correct values make it permanent across reboots by adding them to your startup scripts.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#how-to-disable-trackpoint-on-linux&#34;&gt;How to Disable Trackpoint on Linux.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The trackpoint (that red nub in the middle of ThinkPad keyboards) can be accidentally triggered while typing, or if you replace the keyboard it might make the mouse slide randomly without any user intervention. Here&#39;s how to disable it on Linux systems.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;with xinput&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Get the property of your trackpoint with &lt;code&gt;xinput list | grep -i track&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Then disable the trackpoint with &lt;code&gt;xinput set-prop &#34;TPPS/2 Elan TrackPoint&#34; &#34;Device Enabled&#34; 0&lt;/code&gt;&lt;/p&gt; &lt;p&gt;To make it persistent add that line to your desktop startup scripts. It can be run by a non privileged user.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;With udev rules&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The problem with this approach is that the event number may change across reboots&lt;/p&gt; &lt;p&gt;First, find your trackpoint in the system:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/bus/input/devices&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-A5&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-B5&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;trackpoint
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Look for entries like &#34;TPPS/2 Elan TrackPoint&#34; or similar. Note the event number (e.g., &lt;code&gt;event14&lt;/code&gt;).&lt;/p&gt; &lt;p&gt;Create a udev rule to ignore the trackpoint device:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sh&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;echo &#34;KERNEL==\&#34;event[0-9]*\&#34;, SUBSYSTEM==\&#34;input\&#34;, ATTRS{name}==\&#34;*TrackPoint*\&#34;, ENV{LIBINPUT_IGNORE_DEVICE}=\&#34;1\&#34;&#34; &amp;gt; /etc/udev/rules.d/90-disable-trackpoint.rules&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Replace &lt;code&gt;event[0-9]*&lt;/code&gt; with your specific event number if needed.&lt;/p&gt; &lt;p&gt;Reload udev rules:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;udevadm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;control&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--reload-rules
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;udevadm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;trigger
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Test that the trackpoint no longer responds to input. The udev method typically works immediately and persists across reboots.&lt;/p&gt; &lt;p&gt;This may have an ugly side effect, that you won&#39;t any longer be able to use the touchpad mouse buttons. Sadly the trackpoint and those buttons are controlled by the same device.&lt;/p&gt; &lt;p&gt;The solution is to use the touchpad instead (see below).&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Be able to click using the touchpad&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Activate tap for clicking in touchpad by pasting following lines in /etc/X11/xorg.confg.d/30-touchpad.conf&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Section &#34;InputClass&#34;
    Identifier &#34;touchpad&#34;
    Driver &#34;libinput&#34;
    MatchIsTouchpad &#34;on&#34;
    Option &#34;Tapping&#34; &#34;on&#34;
    Option &#34;TappingButtonMap&#34; &#34;lrm&#34;
EndSection
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The &lt;code&gt;lrm&lt;/code&gt; means that:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;1 finger tap is a left click&lt;/li&gt; &lt;li&gt;2 finger tap is a right click&lt;/li&gt; &lt;li&gt;3 finger tap is a middle click&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;You&#39;ll need to logout and back in for the change to be applied.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#fix-systemd-tmpfiles-detected-unsafe-path-transition-/-→-/dev-during-canonicalization-of-/dev.&#34;&gt;Fix systemd-tmpfiles Detected unsafe path transition / → /dev during canonicalization of /dev.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;with each system start&lt;/p&gt; &lt;p&gt;Here are some examples of the logs: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;systemd-tmpfiles[248]: Detected unsafe path transition / → /dev during canonicalization of /dev.
systemd-tmpfiles[485]: Detected unsafe path transition / → /var during canonicalization of /var.
systemd-tmpfiles[485]: Detected unsafe path transition / → /var during canonicalization of /var/lib.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;This suggests that your root dir, /dev and /var are owned by differing users&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;i3wm&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/i3wm/&#34;&gt;i3wm&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add i3wm python actions.&lt;/p&gt; &lt;p&gt;You can also use it &lt;a href=&#34;https://i3ipc-python.readthedocs.io/en/latest/&#34;&gt;with async&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Create the connection object&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;i3ipc&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Connection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Event&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;i3&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Connection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Focus on a window by it&#39;s class&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;tree&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_tree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;ff&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tree&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;find_classed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Firefox&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;ff&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;focus&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;watchtower&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/canary_tokens/&#34;&gt;Watchtower&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Canary tokens.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.canarytokens.org/nest/&#34;&gt;Canary tokens&lt;/a&gt; are like motion sensors for your networks, computers and clouds. You can put them in folders, on network devices and on your phones.&lt;/p&gt; &lt;p&gt;Place them where nobody should be poking around and get a clear alarm if they are accessed. They are designed to look juicy to attackers to increase the likelihood that they are opened (and they are completely free).&lt;/p&gt; &lt;p&gt;Our Canarytokens are easy to sprinkle all over and forget about, until you get the notification that matters. They are super lightweight and don’t require installing software or running more background processes that can slow down your PC.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://docs.canarytokens.org/guide/&#34;&gt;Docs&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.canarytokens.org/nest/&#34;&gt;Home&lt;/a&gt; feat(kubernetes#Move a pvc between AZ in aws): Move a pvc between AZ in aws&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-e

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-z&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$1&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-z&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$2&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Usage: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$0&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; &amp;lt;pv-name&amp;gt; &amp;lt;new-az&amp;gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;PV_NAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$1&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;NEW_AZ&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$2&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Volume&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ID&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;from&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;PV
&lt;span class=&#34;nv&#34;&gt;VOLUME_ID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PV_NAME&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;jsonpath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;{.spec.csi.volumeHandle}&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-z&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$VOLUME_ID&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed to get volume ID for PV &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PV_NAME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;PVC_NAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PV_NAME&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;jsonpath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;{.spec.claimRef.name}&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;NAMESPACE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pv&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PV_NAME&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;jsonpath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;{.spec.claimRef.namespace}&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;PVC Name: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PVC_NAME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Namespace: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$NAMESPACE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Found volume: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$VOLUME_ID&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;SNAPSHOT_ID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;aws&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ec2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;create-snapshot&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--volume-id&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$VOLUME_ID&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--description&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Migration for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PV_NAME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--query&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;SnapshotId&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--output&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;text&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Snapshot created: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$SNAPSHOT_ID&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Waiting for snapshot to be ready...&#34;&lt;/span&gt;
aws&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ec2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;wait&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;snapshot-completed&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--snapshot-ids&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$SNAPSHOT_ID&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Snapshot &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$SNAPSHOT_ID&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; is ready&#34;&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;VOLUME_TYPE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;aws&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ec2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;describe-volumes&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--volume-ids&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$VOLUME_ID&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--query&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Volumes[0].VolumeType&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--output&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;text&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;NEW_VOLUME_ID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;aws&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ec2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;create-volume&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--snapshot-id&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$SNAPSHOT_ID&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--availability-zone&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$NEW_AZ&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--volume-type&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$VOLUME_TYPE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--query&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;VolumeId&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--output&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;text&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;New volume created: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$NEW_VOLUME_ID&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Waiting for new volume to be available...&#34;&lt;/span&gt;
aws&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ec2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;wait&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;volume-available&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--volume-ids&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$NEW_VOLUME_ID&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;New volume &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$NEW_VOLUME_ID&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; is ready&#34;&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;NEW_PV_NAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;PV_NAME&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;-migrated
cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;lt;&amp;lt;EOF &amp;gt; new-pv.yaml&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;apiVersion: v1&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;kind: PersistentVolume&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;metadata:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  name: $NEW_PV_NAME&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;spec:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  capacity:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;    storage: $(kubectl get pv $PV_NAME -o jsonpath=&#39;{.spec.capacity.storage}&#39;)&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  volumeMode: Filesystem&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  accessModes:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;    - ReadWriteOnce&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  persistentVolumeReclaimPolicy: Retain&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  storageClassName: $(kubectl get pv $PV_NAME -o jsonpath=&#39;{.spec.storageClassName}&#39;)&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  csi:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;    driver: ebs.csi.aws.com&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;    volumeHandle: $NEW_VOLUME_ID&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;    fsType: ext4&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  nodeAffinity:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;    required:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;      nodeSelectorTerms:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;      - matchExpressions:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;        - key: topology.ebs.csi.aws.com/zone&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;          operator: In&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;          values:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;          - $NEW_AZ&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;EOF&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;New PV manifest generated: new-pv.yaml&#34;&lt;/span&gt;

kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apply&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;new-pv.yaml
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;New PV &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$NEW_PV_NAME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; created&#34;&lt;/span&gt;
kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pvc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PVC_NAME&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$NAMESPACE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;yaml&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;PVC_NAME&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;-backup.yaml

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;If you haven&#39;t size to 0 the statefulset, it is the time to kill the pod to rebind the PVC&#34;&lt;/span&gt;

kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;delete&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pvc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PVC_NAME&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$NAMESPACE&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Old PVC deleted&#34;&lt;/span&gt;
cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;lt;&amp;lt;EOF &amp;gt; new-pvc.yaml&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;apiVersion: v1&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;kind: PersistentVolumeClaim&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;metadata:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  name: $PVC_NAME&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  namespace: $NAMESPACE&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;spec:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  accessModes:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;    - ReadWriteOnce&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  resources:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;    requests:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;      storage: $(kubectl get pv $NEW_PV_NAME -o jsonpath=&#39;{.spec.capacity.storage}&#39;)&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  storageClassName: $(kubectl get pv $NEW_PV_NAME -o jsonpath=&#39;{.spec.storageClassName}&#39;)&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  volumeName: $NEW_PV_NAME&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;EOF&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;New PVC manifest generated: new-pvc.yaml&#34;&lt;/span&gt;

kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apply&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;new-pvc.yaml
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;New PVC &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PVC_NAME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; created and bound to new PV&#34;&lt;/span&gt;

kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;delete&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PV_NAME&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed to delete PV &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PV_NAME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;, probably was not retained&#34;&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Old PV &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PV_NAME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; deleted&#34;&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Deleting old volume &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$VOLUME_ID&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
aws&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ec2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;delete-volume&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--volume-id&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$VOLUME_ID&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed to delete volume &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$VOLUME_ID&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;, probably was not retained&#34;&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Old volume deleted&#34;&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Deleting snapshot &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$SNAPSHOT_ID&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;aws&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ec2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;delete-snapshot&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--snapshot-id&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$SNAPSHOT_ID&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Snapshot deleted&#34;&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-e&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Migration complete.\nNew PV: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$NEW_PV_NAME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;\nNew PVC: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PVC_NAME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Error opening terminal: xterm-kitty.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/kovidgoyal/kitty/issues/1613&#34;&gt;The not so good solution but that solves the issue is&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;TERM&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;xterm
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Change the default docker image.&lt;/p&gt; &lt;p&gt;From &lt;code&gt;containrrr/watchtower&lt;/code&gt; to &lt;code&gt;nickfedor/watchtower&lt;/code&gt;. &lt;a href=&#34;https://github.com/containrrr/watchtower/issues/2122&#34;&gt;The official repo has not been updated in a while&lt;/a&gt; use &lt;a href=&#34;https://github.com/nicholas-fedor/watchtower&#34;&gt;this fork instead&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;mobile-keyboards&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/mobile_keyboards/&#34;&gt;Mobile Keyboards&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce mobile keyboards comparison.&lt;/p&gt; &lt;p&gt;Finding the right mobile keyboard that balances functionality, privacy, and usability can be challenging. This guide explores the best open-source and privacy-focused keyboard options available for Android devices.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Quick Recommendations&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;For Gboard users transitioning&lt;/strong&gt;: HeliBoard&lt;/li&gt; &lt;li&gt;&lt;strong&gt;For advanced features and AI&lt;/strong&gt;: FUTO Keyboard&lt;/li&gt; &lt;li&gt;&lt;strong&gt;For unique input method&lt;/strong&gt;: Thumb-Key&lt;/li&gt; &lt;li&gt;&lt;strong&gt;For future consideration&lt;/strong&gt;: FlorisBoard (when stable)&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;FUTO Keyboard ⭐ Recommended&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;FUTO represents the cutting edge of privacy-focused keyboard technology, incorporating AI features while maintaining offline functionality.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;What Makes FUTO Special&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;FUTO stands out with &lt;strong&gt;transformer-based predictions&lt;/strong&gt; using llama.cpp and &lt;strong&gt;integrated voice input&lt;/strong&gt; powered by whisper.cpp. Unlike other keyboards that require proprietary libraries, FUTO includes swipe/glide typing by default.&lt;/p&gt; &lt;p&gt;The keyboard is currently in pre-alpha, so expect some bugs and missing features. However, the privacy-preserving approach and innovative AI integration make it worth trying.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Smart Text Prediction&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Uses pre-trained transformer models for intelligent autocorrect&lt;/li&gt; &lt;li&gt;Personal language model that learns from your typing (locally only)&lt;/li&gt; &lt;li&gt;Currently optimized for English, with other languages in development&lt;/li&gt; &lt;li&gt;Spanish support is still limited&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Privacy-First Design&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;All AI processing happens on-device&lt;/li&gt; &lt;li&gt;Your data never leaves your phone&lt;/li&gt; &lt;li&gt;FUTO doesn&#39;t view or store any typing data&lt;/li&gt; &lt;li&gt;Internet access only for updates and crash reporting (planned to be removed)&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Customization Options&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Multilingual typing support&lt;/li&gt; &lt;li&gt;Custom keyboard layouts&lt;/li&gt; &lt;li&gt;Swipe typing works well out of the box&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Current Limitations&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Pre-alpha software with occasional bugs&lt;/li&gt; &lt;li&gt;Limited language support beyond English&lt;/li&gt; &lt;li&gt;Uses a custom &#34;Source First&#34; license (not traditional open source)&lt;/li&gt; &lt;li&gt;Screen movement issues when using swipe typing&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Licensing Concerns&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;FUTO uses a custom license rather than traditional open source licenses like GPL. While the source code is available, the licensing terms are more restrictive than typical open source projects. The team promises to adopt proper open source licensing eventually, but this transition hasn&#39;t happened yet.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://keyboard.futo.org/&#34;&gt;Official Website&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://docs.keyboard.futo.org/&#34;&gt;Documentation&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://gitlab.futo.org/alex/voiceinput&#34;&gt;Source Code&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://privseclaw.info/posts/futokeyboard/&#34;&gt;Privacy Analysis&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Not there yet&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The futo voice has a weird bug at least in spanish that sometimes adds at the end of the transcription phrases like: Subscribe! or Chau or Thanks for watching my video!. This is kind of annoying and scary &lt;code&gt;(¬º-°)¬&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;HeliBoard - The Reliable Choice&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;HeliBoard serves as an excellent middle ground, especially for users transitioning from Gboard.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Why Choose HeliBoard&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Active development&lt;/strong&gt;: Fork of OpenBoard with regular updates&lt;/li&gt; &lt;li&gt;&lt;strong&gt;No network access&lt;/strong&gt;: Completely offline operation&lt;/li&gt; &lt;li&gt;&lt;strong&gt;User-friendly&lt;/strong&gt;: Much simpler than AnySoftKeyboard&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Gboard-like experience&lt;/strong&gt;: Familiar interface for Google Keyboard users&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Trade-offs&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The main limitation is glide typing, which requires a closed-source library. This compromises the fully open source nature but provides the swipe functionality many users expect.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/Helium314/HeliBoard&#34;&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Thumb-Key - The Innovative Alternative&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;For users willing to try something completely different, Thumb-Key offers a unique approach to mobile typing.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;The Thumb-Key Concept&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Instead of traditional QWERTY, Thumb-Key uses a &lt;strong&gt;3x3 grid layout&lt;/strong&gt; with swipe gestures for less common letters. This design prioritizes:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Large, predictable key positions&lt;/li&gt; &lt;li&gt;Muscle memory development&lt;/li&gt; &lt;li&gt;Eyes staying on the text area&lt;/li&gt; &lt;li&gt;Fast typing speeds once mastered&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Best For&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Users open to learning new input methods&lt;/li&gt; &lt;li&gt;Those who prefer larger touch targets&lt;/li&gt; &lt;li&gt;Privacy enthusiasts who want to avoid predictive text entirely&lt;/li&gt; &lt;li&gt;People who find traditional keyboards cramped&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The keyboard is highly configurable and focuses on accuracy through key positioning rather than AI predictions.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/dessalines/thumb-key&#34;&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;FlorisBoard - Future Potential&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;FlorisBoard shows promise but isn&#39;t ready for daily use yet.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Current Status&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Early beta development&lt;/li&gt; &lt;li&gt;Planned integration with GrapheneOS&lt;/li&gt; &lt;li&gt;Missing key features like suggestions and glide typing&lt;/li&gt; &lt;li&gt;Limited documentation available&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Worth Watching&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;While not currently recommended for primary use, FlorisBoard could become a strong contender once it reaches stability.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/florisboard/florisboard&#34;&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://florisboard.org/&#34;&gt;Official Website&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Alternative Approaches&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Unexpected Keyboard&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;A minimalist keyboard with a unique layout approach.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/Julow/Unexpected-Keyboard&#34;&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Using Proprietary Keyboards with Restrictions&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;On privacy-focused ROMs like GrapheneOS and DivestOS, you can use proprietary keyboards while blocking internet access. However, this approach has limitations due to inter-process communication between apps.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This method isn&#39;t foolproof, as apps can still potentially communicate through IPC mechanisms.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;My Current Setup&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;After testing various options:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Primary choice&lt;/strong&gt;: FUTO Keyboard with swipe enabled&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Backup plan&lt;/strong&gt;: Try FUTO voice input for longer texts when privacy features improve&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Alternative&lt;/strong&gt;: Thumb-Key if FUTO doesn&#39;t work out&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;The main issue encountered is screen movement during swipe typing, which may be device-specific.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References and Further Reading&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://discuss.privacyguides.net/t/recommend-open-source-android-keyboards/17808/36&#34;&gt;Privacy Guides Discussion on Android Keyboards&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://discuss.privacyguides.net/t/futo-keyboard/18896&#34;&gt;FUTO Keyboard Community Discussion&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/GrapheneOS/os-issue-tracker/issues/2810&#34;&gt;GrapheneOS IPC Communication Issue&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;wireguard&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/wireguard/&#34;&gt;Wireguard&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/wireguard/#configure-the-kill-switch&#34;&gt;Configure the kill switch.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can configure a kill-switch in order to prevent the flow of unencrypted packets through the non-WireGuard interfaces, by adding the following two lines ‘PostUp‘ and ‘PreDown‘ lines to the ‘[Interface]‘ section:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;PostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
PreDown = iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The ‘PostUp’ and ‘PreDown’ fields have been added to specify an iptables command which, when used with interfaces that have a peer that specifies 0.0.0.0/0 as part of the ‘AllowedIPs’, works together with wg-quick’s fwmark usage in order to drop all packets that are either not coming out of the tunnel encrypted or not going through the tunnel itself. Note that this continues to allow most DHCP traffic through, since most DHCP clients make use of PF_PACKET sockets, which bypass Netfilter. When IPv6 is in use, additional similar lines could be added using ip6tables.&lt;/p&gt; &lt;p&gt;If you want to allow the traffic to your LAN while keeping your kill-switch you can use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;PostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT &amp;amp;&amp;amp; iptables -I OUTPUT -p tcp -d 192.168.0.0/24 -j ACCEPT
PreDown = iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT &amp;amp;&amp;amp; iptables -D OUTPUT -p tcp -d 192.168.0.0/24 -j ACCEPT
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Here I&#39;m assuming that your LAN is defined by &lt;code&gt;192.168.0.0/24&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.ivpn.net/knowledgebase/linux/linux-wireguard-kill-switch/&#34;&gt;One way to test if the kill switch works&lt;/a&gt; is by deleting the IP address from the wireguard interface&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;del&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;IP&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;address&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;interface&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where the &lt;code&gt;[IP address]&lt;/code&gt; can be seen using the &lt;code&gt;ip a&lt;/code&gt; command.&lt;/p&gt; &lt;p&gt;To gracefully recover from this, you will likely have to use the wg-quick command to take the connection down, then bring it back up.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/wireguard/#user-management&#34;&gt;User management.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Wireguard&#39;s default user management is not very user friendly as it&#39;s difficult to know which key belongs to what user.&lt;/p&gt; &lt;p&gt;I&#39;ve been looking for WireGuard admin interface UI that is actively maintained but also isn&#39;t cloud-based and &lt;a href=&#34;https://www.reddit.com/r/selfhosted/comments/18nrbnf/wireguard_admin_interface_ui_that_is_actively/&#34;&gt;between all solutions&lt;/a&gt; I found &lt;a href=&#34;https://lyz-code.github.io/blue-book/wg-easy/&#34;&gt;wg-easy&lt;/a&gt; the best candidate because:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;It has just the features I need:&lt;/li&gt; &lt;li&gt;Clean User management: add, remove, disable&lt;/li&gt; &lt;li&gt;Clean UI interface&lt;/li&gt; &lt;li&gt;Actively maintained: last commit 7h ago&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/wg-easy/wg-easy/tree/master&#34;&gt;Really popular: 17.7k stars, 1.7k forks&lt;/a&gt;&lt;/li&gt; &lt;li&gt;It&#39;s installable either with docker or &lt;a href=&#34;https://github.com/wg-easy/wg-easy/blob/production/docker-compose.yml&#34;&gt;docker-compose&lt;/a&gt;&lt;/li&gt; &lt;li&gt;It exports &lt;a href=&#34;https://github.com/wg-easy/wg-easy/issues/1510&#34;&gt;prometheus metrics&lt;/a&gt;&lt;/li&gt; &lt;li&gt;It has &lt;a href=&#34;https://github.com/wg-easy/wg-easy/wiki&#34;&gt;good documentation&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;It has &lt;a href=&#34;https://github.com/wg-easy/wg-easy/wiki/Using-WireGuard-Easy-with-Ansible&#34;&gt;an ansible playbook&lt;/a&gt;&lt;/li&gt; &lt;li&gt;It has &lt;a href=&#34;https://grafana.com/grafana/dashboards/21733-wireguard/&#34;&gt;a grafana dashboard&lt;/a&gt;&lt;/li&gt; &lt;li&gt;It has &lt;a href=&#34;https://github.com/wg-easy/wg-easy/tree/master&#34;&gt;a clean release process&lt;/a&gt;&lt;/li&gt; &lt;li&gt;It&#39;s a stable project: 3 years and 10 months old&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;If &lt;code&gt;wg-easy&lt;/code&gt; doesn&#39;t work, I&#39;d look at the next projects:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/donaldzou/WGDashboard?tab=readme-ov-file&#34;&gt;WGDashboard&lt;/a&gt; (&lt;a href=&#34;https://donaldzou.dev/WGDashboard-Documentation/index_topic.html&#34;&gt;Docs&lt;/a&gt;)&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/burghardt/easy-wg-quick&#34;&gt;easy-wg-quick&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/ngoduykhanh/wireguard-ui&#34;&gt;wireguard-ui&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/gene-git/wg_tool&#34;&gt;wg-tool&lt;/a&gt; and &lt;a href=&#34;https://github.com/gene-git/wg-client&#34;&gt;wg-client&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/wireguard/#rosenpass&#34;&gt;Introduce Rosenpass.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Rosenpass is free and open-source software based on the latest research in the field of cryptography. It is intended to be used with WireGuard VPN, but can work with all software that uses pre-shared keys. It uses two cryptographic methods (Classic McEliece and Kyber) to secure systems against attacks with quantum computers.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/rosenpass/rosenpass&#34;&gt;Source code&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://rosenpass.eu/docs/&#34;&gt;Docs&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/wireguard/#references&#34;&gt;Add awesome wireguard link.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/cedrickchee/awesome-wireguard&#34;&gt;Awesome wireguard&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce wg-easy.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/wg-easy/wg-easy/tree/master&#34;&gt;&lt;code&gt;wg-easy&lt;/code&gt;&lt;/a&gt; is the easiest way to install &amp;amp; manage WireGuard on any Linux hostthe easiest way to install &amp;amp; manage WireGuard on any Linux host&lt;/p&gt; &lt;p&gt;Features:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;All-in-one: WireGuard + Web UI.&lt;/li&gt; &lt;li&gt;Easy installation, simple to use.&lt;/li&gt; &lt;li&gt;List, create, edit, delete, enable &amp;amp; disable clients.&lt;/li&gt; &lt;li&gt;Show a client&#39;s QR code.&lt;/li&gt; &lt;li&gt;Download a client&#39;s configuration file.&lt;/li&gt; &lt;li&gt;Statistics for which clients are connected.&lt;/li&gt; &lt;li&gt;Tx/Rx charts for each connected client.&lt;/li&gt; &lt;li&gt;Gravatar support.&lt;/li&gt; &lt;li&gt;Automatic Light / Dark Mode&lt;/li&gt; &lt;li&gt;Multilanguage Support&lt;/li&gt; &lt;li&gt;One Time Links&lt;/li&gt; &lt;li&gt;Client Expiration&lt;/li&gt; &lt;li&gt;Prometheus metrics support&lt;/li&gt; &lt;li&gt;IPv6 support&lt;/li&gt; &lt;li&gt;CIDR support&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/wg-easy/wg-easy/tree/master?tab=readme-ov-file#installation&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/wg-easy/wg-easy/wiki/Using-WireGuard-Easy-with-Ansible&#34;&gt;With ansible&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/wg-easy/wg-easy/tree/master&#34;&gt;Source&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/wg-easy/wg-easy/wiki&#34;&gt;Docs&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#39;../../linux/wireguard/#failed-to-resolve-interface-&#34;tun&#34;:-no-such-device&#39;&gt;Troubleshoot Failed to resolve interface &#34;tun&#34;: No such device.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;purge&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;resolvconf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: More wg-easy configurations.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/wg-easy/wg-easy/wiki/Using-WireGuard-Easy-with-Ansible&#34;&gt;configure with ansible&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Configuration&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/wg-easy/wg-easy/pull/737&#34;&gt;Split tunneling&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Keep in mind though that the &lt;code&gt;WG_ALLOWED_IPS&lt;/code&gt; only sets the routes on the client, it does not limit the traffic at server level. For example, if you set &lt;code&gt;172.30.1.0/24&lt;/code&gt; as the allowed ips, but the client changes it to &lt;code&gt;172.30.0.0/16&lt;/code&gt; it will be able to access for example &lt;code&gt;172.30.2.1&lt;/code&gt;. The suggested way to prevent this behavior is to add the kill switch in the Pre and Post hooks (&lt;code&gt;WG_POST_UP&lt;/code&gt; and &lt;code&gt;WG_POST_DOWN&lt;/code&gt;)&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/wg-easy/wg-easy/wiki/Restrict-Access-to-Networks-with-iptables&#34;&gt;Restrict Access to Networks with iptables&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you need to restrict many networks you can use &lt;a href=&#34;https://www.procustodibus.com/blog/2021/03/wireguard-allowedips-calculator/&#34;&gt;this allowed ips calculator&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://airvpn.org/forums/topic/50601-kill-switch-settings-for-wireguard-on-ubuntu-20/&#34;&gt;Kill switch&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Monitorization&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you want to use the prometheus metrics &lt;a href=&#34;https://github.com/wg-easy/wg-easy/issues/1373&#34;&gt;you need to use a version greater than 14&lt;/a&gt;, as &lt;code&gt;15&lt;/code&gt; is &lt;a href=&#34;https://github.com/wg-easy/wg-easy/pkgs/container/wg-easy/versions&#34;&gt;not yet released&lt;/a&gt; (as of 2025-03-20) I&#39;m using &lt;code&gt;nightly&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;You can enable them with the environment variable &lt;code&gt;ENABLE_PROMETHEUS_METRICS=true&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Scrape the metrics&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Add to your scrape config the required information&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;job_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;vpn-admin&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metrics_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/metrics&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;static_configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;targets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;your vpn private ip&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;:{your vpn exporter port}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Create the monitor client&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To make sure that the vpn is working we&#39;ll add a client that is always connected. To do so we&#39;ll use &lt;a href=&#34;https://github.com/linuxserver/docker-wireguard&#34;&gt;linuxserver&#39;s wireguard docker&lt;/a&gt;&lt;/p&gt; &lt;p&gt;# References&lt;/p&gt; &lt;p&gt;diff --git a/mkdocs.yml b/mkdocs.yml index 77e5ba92b2..ef6703047d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -86,6 +86,7 @@ nav: - Trip management: - Route management: route_management.md - Map management: map_management.md + - dawarich: dawarich.md - Food management: food_management.md - Stock management: - Grocy: grocy_management.md @@ -212,514 +213,522 @@ nav: - Fitness Tracker: - fitness_band.md - Amazfit Band 5: amazfit_band_5.md - - Coding: - - Learning to code: - - code_learning.md - - Frontend developer: frontend_learning.md - - Languages: - - Python: - - python.md - - Project Template: - - coding/python/python_project_template.md - - Command-line Project Template: - - coding/python/python_project_template/python_cli_template.md - - Configure SQLAlchemy for projects without flask: &amp;gt;- - coding/python/python_project_template/python_sqlalchemy_without_flask.md - - Flask Project Template: &amp;gt;- - coding/python/python_project_template/python_flask_template.md - - Microservices Project Template: &amp;gt;- - coding/python/python_project_template/python_microservices_template.md - - Common configurations: - - Create the documentation repository: &amp;gt;- - coding/python/python_project_template/python_docs.md - - Load config from YAML: coding/python/python_config_yaml.md - - Configure SQLAlchemy to use the MariaDB/Mysql backend: - &amp;gt;- - coding/python/python_project_template/python_sqlalchemy_mariadb.md - - Configure Docker to host the application: &amp;gt;- - coding/python/python_project_template/python_docker.md - - Libraries: - - Alembic: coding/python/alembic.md - - asyncio: asyncio.md - - aiocron: aiocron.md - - Apprise: apprise.md - - aiohttp: aiohttp.md - - BeautifulSoup: beautifulsoup.md - - Boto3: boto3.md - - Click: coding/python/click.md - - Dash: coding/python/dash.md - - Dash Leaflet: coding/python/dash_leaflet.md - - DeepDiff: coding/python/deepdiff.md - - FactoryBoy: coding/python/factoryboy.md - - Faker: coding/python/faker.md - - FastAPI: fastapi.md - - Flask: coding/python/flask.md - - Flask Restplus: coding/python/flask_restplus.md - - Folium: coding/python/folium.md - - Feedparser: coding/python/feedparser.md - - Gettext: gettext.md - - GitPython: coding/python/gitpython.md - - Goodconf: goodconf.md - - ICS: ics.md - - Inotify: python_inotify.md - - watchdog: watchdog_python.md - - Jinja2: python_jinja2.md - - Maison: maison.md - - mkdocstrings: coding/python/mkdocstrings.md - - NetworkX: networkx.md - - Org-rw: org_rw.md - - Pandas: coding/python/pandas.md - - Passpy: coding/python/passpy.md - - pexpect: pexpect.md - - Prompt Toolkit: - - coding/python/prompt_toolkit.md - - REPL: prompt_toolkit_repl.md - - Full screen applications: prompt_toolkit_fullscreen_applications.md - - Pydantic: - - coding/python/pydantic.md - - Pydantic Field Types: coding/python/pydantic_types.md - - Pydantic Validators: coding/python/pydantic_validators.md - - Pydantic Exporting Models: coding/python/pydantic_exporting.md - - Pydantic Validating Functions: coding/python/pydantic_functions.md - - Pydantic Factories: pydantic_factories.md - - Pydantic Mypy Plugin: coding/python/pydantic_mypy_plugin.md - - Pypika: coding/python/pypika.md - - psycopg2: psycopg2.md - - Elasticsearch: python_elasticsearch.md - - python-gnupg: python_gnupg.md - - Python Mysql: python_mysql.md - - pythonping: pythonping.md + - Technology: + - Coding: + - Learning to code: + - code_learning.md + - Frontend developer: frontend_learning.md + - Languages: + - Python: + - python.md + - Project Template: + - coding/python/python_project_template.md + - Command-line Project Template: + - coding/python/python_project_template/python_cli_template.md + - Configure SQLAlchemy for projects without flask: &amp;gt;- + coding/python/python_project_template/python_sqlalchemy_without_flask.md + - Flask Project Template: &amp;gt;- + coding/python/python_project_template/python_flask_template.md + - Microservices Project Template: &amp;gt;- + coding/python/python_project_template/python_microservices_template.md + - Common configurations: + - Create the documentation repository: &amp;gt;- + coding/python/python_project_template/python_docs.md + - Load config from YAML: coding/python/python_config_yaml.md + - Configure SQLAlchemy to use the MariaDB/Mysql backend: + &amp;gt;- + coding/python/python_project_template/python_sqlalchemy_mariadb.md + - Configure Docker to host the application: &amp;gt;- + coding/python/python_project_template/python_docker.md + - Libraries: + - Alembic: coding/python/alembic.md + - asyncio: asyncio.md + - aiocron: aiocron.md + - Apprise: apprise.md + - aiohttp: aiohttp.md + - BeautifulSoup: beautifulsoup.md + - Boto3: boto3.md + - Click: coding/python/click.md + - Dash: coding/python/dash.md + - Dash Leaflet: coding/python/dash_leaflet.md + - DeepDiff: coding/python/deepdiff.md + - FactoryBoy: coding/python/factoryboy.md + - Faker: coding/python/faker.md + - FastAPI: fastapi.md + - Flask: coding/python/flask.md + - Flask Restplus: coding/python/flask_restplus.md + - Folium: coding/python/folium.md + - Feedparser: coding/python/feedparser.md + - Gettext: gettext.md + - GitPython: coding/python/gitpython.md + - Goodconf: goodconf.md + - ICS: ics.md + - Inotify: python_inotify.md + - watchdog: watchdog_python.md + - Jinja2: python_jinja2.md + - Maison: maison.md + - mkdocstrings: coding/python/mkdocstrings.md + - NetworkX: networkx.md + - Org-rw: org_rw.md + - Pandas: coding/python/pandas.md + - Passpy: coding/python/passpy.md + - pexpect: pexpect.md + - Prompt Toolkit: + - coding/python/prompt_toolkit.md + - REPL: prompt_toolkit_repl.md + - Full screen applications: prompt_toolkit_fullscreen_applications.md + - Pydantic: + - coding/python/pydantic.md + - Pydantic Field Types: coding/python/pydantic_types.md + - Pydantic Validators: coding/python/pydantic_validators.md + - Pydantic Exporting Models: coding/python/pydantic_exporting.md + - Pydantic Validating Functions: coding/python/pydantic_functions.md + - Pydantic Factories: pydantic_factories.md + - Pydantic Mypy Plugin: coding/python/pydantic_mypy_plugin.md + - Pypika: coding/python/pypika.md + - psycopg2: psycopg2.md + - Elasticsearch: python_elasticsearch.md + - python-gnupg: python_gnupg.md + - Python Mysql: python_mysql.md + - pythonping: pythonping.md + - Python Prometheus: python-prometheus.md + - Python Telegram: + - python-telegram.md + - pytelegrambotapi: pytelegrambotapi.md + - Python VLC: python_vlc.md + - Playwright: playwright.md + - Plotly: coding/python/plotly.md + - questionary: questionary.md + - rich: rich.md + - Ruamel YAML: coding/python/ruamel_yaml.md + - Selenium: selenium.md + - Streamlit: streamlit.md + - SQLAlchemy: coding/python/sqlalchemy.md + - sqlite3: sqlite3.md + - Redis-py: coding/python/redis-py.md + - Requests: requests.md + - Requests-mock: coding/python/requests_mock.md + - Rq: coding/python/rq.md + - python_systemd: python_systemd.md + - sh: python_sh.md + - Talkey: talkey.md + - Tenacity: tenacity.md + - TinyDB: coding/python/tinydb.md + - Torch: torch.md + - Typer: typer.md + - Yoyo: coding/python/yoyo.md + - Type Hints: coding/python/type_hints.md + - Logging: python_logging.md + - Code Styling: coding/python/python_code_styling.md + - Docstrings: coding/python/docstrings.md + - Properties: python_properties.md + - Protocols: python_protocols.md + - Package Management: + - python_package_management.md + - PDM: pdm.md + - pipx: pipx.md + - Pipenv: pipenv.md + - Poetry: python_poetry.md + - Lazy loading: lazy_loading.md + - Plugin System: python_plugin_system.md + - Profiling: python_profiling.md + - Optimization: python_optimization.md + - Anti-Patterns: coding/python/python_anti_patterns.md + - Pytest: + - coding/python/pytest.md + - Parametrized testing: coding/python/pytest_parametrized_testing.md + - Pytest-cases: coding/python/pytest_cases.md + - Pytest-HttpServer: pytest_httpserver.md + - Pytest-xprocess: pytest-xprocess.md + - Internationalization: python_internationalization.md + - Python Snippets: coding/python/python_snippets.md + - Data Classes: coding/python/data_classes.md + - Vue.js: + - vuejs.md + - Vue snippets: vue_snippets.md + - Vuetify: vuetify.md + - Development tools: + - Cypress: cypress.md + - Vite: vite.md + - Vitest: vitest.md + - Bash: + - Bash snippets: bash_snippets.md + - Bash testing: bats.md + - lua: lua.md + - JSON: coding/json/json.md + - SQL: coding/sql/sql.md + - SQLite: sqlite.md + - YAML: coding/yaml/yaml.md + - Promql: coding/promql/promql.md + - Logql: logql.md + - HTML: html.md + - CSS: css.md + - Javascript: + - coding/javascript/javascript.md + - Javascript snippets: javascript_snippets.md + - MermaidJS: mermaidjs.md + - Latex: latex.md + - Graphql: graphql.md + - Qwik: qwik.md + - nodejs: linux/nodejs.md + - JWT: devops/jwt.md + - React: coding/react/react.md + - Coding tools: + - IDES: + - Vim: + - vim.md + - Vim configuration: + - vim_config.md + - Vim Keymaps: vim_keymaps.md + - Vim Package Manager: + - vim_plugin_managers.md + - LazyVim: lazyvim.md + - Packer: vim_packer.md + - UI management configuration: + - Vim foldings: vim_foldings.md + - Vim movement: vim_movement.md + - Tabs vs Buffers: vim_tabs.md + - File management configuration: + - NeoTree: neotree.md + - Telescope: telescope.md + - fzf.nvim: fzf_nvim.md + - Editing specific configuration: + - vim_editor_plugins.md + - Vim formatters: vim_formatters.md + - Vim autocomplete: vim_completion.md + - Vim markdown: vim_markdown.md + - Vim spelling: vim_spelling.md + - Vim autosave: vim_autosave.md + - Coding specific configuration: + - vim_coding_plugins.md + - Treesitter: vim_treesitter.md + - LSP: vim_lsp.md + - Snippets: luasnip.md + - DAP: vim_dap.md + - Git management configuration: + - vim_git.md + - Diffview: diffview.md + - gitsigns: gitsigns.md + - Testing management configuration: vim_testing.md + - Email management: vim_email.md + - Other Vim Plugins: + - linux/vim/vim_plugins.md + - Vim Snippets: vim_snippets.md + - Vim Troubleshooting: vim_troubleshooting.md + - Neovim Plugin Development: vim_plugin_development.md + - Vi vs Vim vs Neovim: vim_vs_neovim.md + - Tridactyl: tridactyl.md + - VSCodium: vscodium.md + - Coding with AI: ai_coding.md + - Git: + - git.md + - Github cli: gh.md + - Forgejo: forgejo.md + - Gitea: gitea.md + - Radicle: radicle.md + - Data orchestrators: + - data_orchestrators.md + - Kestra: kestra.md + - memorious: memorious.md + - Scrapers: + - morph.io: morph_io.md + - ETL: + - Singer: singer.md + - Espanso: espanso.md + - Generic Coding Practices: + - How to code: how_to_code.md + - Program Versioning: + - versioning.md + - Semantic Versioning: semantic_versioning.md + - Calendar Versioning: calendar_versioning.md + - Use warnings to evolve your code: use_warnings.md + - Keep a Changelog: changelog.md + - Writing good documentation: documentation.md + - Conventional comments: conventional_comments.md + - TDD: coding/tdd.md + - GitOps: gitops.md + - Abstract Syntax Trees: abstract_syntax_trees.md + - Software Architecture: + - SOLID: architecture/solid.md + - Domain Driven Design: + - architecture/domain_driven_design.md + - Repository Pattern: architecture/repository_pattern.md + - Service Layer Pattern: architecture/service_layer_pattern.md + - Architecture Decision Record: adr.md + - Database Architecture: architecture/database_architecture.md + - ORM, Query Builder or Raw SQL: architecture/orm_builder_query_or_raw_sql.md + - Microservices: architecture/microservices.md + - Restful APIS: architecture/restful_apis.md + - OCR: + - Table parsing: + - Camelot: camelot.md + - Frontend Development: frontend_development.md + - Park programming: park_programming.md + - Sponsor: sponsor.md + - Issues: issues.md + - DevSecOps: + - devops/devops.md + - Infrastructure as Code: + - Helm: + - devops/helm/helm.md + - Helm Installation: devops/helm/helm_installation.md + - Helm Commands: devops/helm/helm_commands.md + - Helm Secrets: devops/helm/helm_secrets.md + - Helm Git: helm_git.md + - Helmfile: devops/helmfile.md + - Terraform: terraform.md + - Ansible: + - Ansible Snippets: ansible_snippets.md + - Molecule: molecule.md + - Nix: nix.md + - Dotfiles: + - dotfiles.md + - Home Manager: home-manager.md + - Chezmoi: chezmoi.md + - Dotdrop: dotdrop.md + - Infrastructure Solutions: + - Kubernetes: + - devops/kubernetes/kubernetes.md + - Architecture: devops/kubernetes/kubernetes_architecture.md + - Resources: + - Namespaces: devops/kubernetes/kubernetes_namespaces.md + - Pods: devops/kubernetes/kubernetes_pods.md + - ReplicaSets: devops/kubernetes/kubernetes_replicasets.md + - Deployments: devops/kubernetes/kubernetes_deployments.md + - Horizontal Pod Autoscaling: &amp;gt;- + devops/kubernetes/kubernetes_hpa.md + - Volumes: devops/kubernetes/kubernetes_volumes.md + - Services: devops/kubernetes/kubernetes_services.md + - Labels: devops/kubernetes/kubernetes_labels.md + - Annotations: devops/kubernetes/kubernetes_annotations.md + - Ingress: devops/kubernetes/kubernetes_ingress.md + - Jobs: devops/kubernetes/kubernetes_jobs.md + - Kubectl: + - devops/kubectl/kubectl.md + - Kubectl Installation: devops/kubectl/kubectl_installation.md + - Kubectl Commands: devops/kubectl/kubectl_commands.md + - Additional Components: + - Metrics Server: devops/kubernetes/kubernetes_metric_server.md + - Ingress Controller: &amp;gt;- + devops/kubernetes/kubernetes_ingress_controller.md + - External DNS: devops/kubernetes/kubernetes_external_dns.md + - Cluster Autoscaler: &amp;gt;- + devops/kubernetes/kubernetes_cluster_autoscaler.md + - Dashboard: devops/kubernetes/kubernetes_dashboard.md + - Storage Driver: devops/kubernetes/kubernetes_storage_driver.md + - Vertical Pod Autoscaler: &amp;gt;- + devops/kubernetes/kubernetes_vertical_pod_autoscaler.md + - Networking: devops/kubernetes/kubernetes_networking.md + - Debugging: kubernetes_debugging.md + - Backups: + - Velero: velero.md + - Operators: devops/kubernetes/kubernetes_operators.md + - Tools: + - devops/kubernetes/kubernetes_tools.md + - Krew: krew.md + - Ksniff: ksniff.md + - Mizu: mizu.md + - AWS: + - devops/aws/aws.md + - AWS Snippets: aws_snippets.md + - AWS Savings plan: aws_savings_plan.md + - Security groups workflow: devops/aws/security_groups.md + - EKS: devops/aws/eks.md + - EFS: efs.md + - IAM: + - devops/aws/iam/iam.md + - IAM Commands: devops/aws/iam/iam_commands.md + - IAM Debugging: devops/aws/iam/iam_debug.md + - S3: devops/aws/s3.md + - WAF: aws_waf.md + - Databases: + - Redis: architecture/redis.md + - RabbitMQ: rabbitmq.md + - Continuous Deployment: + - ArgoCD: argocd.md + - Continuous Integration: + - devops/ci.md + - Drone: drone.md + - Linters: + - Alex: devops/alex.md + - Flakeheaven: flakeheaven.md + - Flake8: devops/flake8.md + - Markdownlint: devops/markdownlint.md + - Proselint: devops/proselint.md + - Shellcheck: shellcheck.md + - Yamllint: devops/yamllint.md + - Write Good: devops/write_good.md + - Formatters/Fixers: + - Black: devops/black.md + - Yamlfix: yamlfix.md + - Pyment: pyment.md + - mdformat: mdformat.md + - Type Checkers: + - Mypy: devops/mypy.md + - Security Checkers: + - pip-audit: pip_audit.md + - Bandit: devops/bandit.md + - Safety: devops/safety.md + - Dependency managers: + - Pip-tools: devops/pip_tools.md + - Automating Processes: + - copier: copier.md + - cookiecutter: linux/cookiecutter.md + - cruft: linux/cruft.md + - renovate: renovate.md + - letsencrypt: letsencrypt.md + - Threat modeling: + - Privacy threat modeling: privacy_threat_modeling.md + - Storage: + - storage.md + - NAS: nas.md + - OpenZFS: + - linux/zfs.md + - OpenZFS storage planning: zfs_storage_planning.md + - Sanoid: sanoid.md + - ZFS Prometheus exporter: zfs_exporter.md + - Hard drive health: + - hard_drive_health.md + - Smartctl: smartctl.md + - badblocks: badblocks.md + - Resilience: + - linux_resilience.md + - Memtest: memtest.md + - watchdog: watchdog.md + - Magic keys: magic_keys.md + - Monitoring: + - Monitoring Comparison: monitoring_comparison.md + - Prometheus: + - devops/prometheus/prometheus.md + - Architecture: devops/prometheus/prometheus_architecture.md + - Prometheus Operator: devops/prometheus/prometheus_operator.md + - Prometheus Install: devops/prometheus/prometheus_installation.md + - AlertManager: devops/prometheus/alertmanager.md + - Blackbox Exporter: devops/prometheus/blackbox_exporter.md + - cAdvisor: cadvisor.md + - Elasticsearch Exporter: elasticsearch_exporter.md + - Node Exporter: devops/prometheus/node_exporter.md + - Process Exporter: process_exporter.md - Python Prometheus: python-prometheus.md - - Python Telegram: - - python-telegram.md - - pytelegrambotapi: pytelegrambotapi.md - - Python VLC: python_vlc.md - - Playwright: playwright.md - - Plotly: coding/python/plotly.md - - questionary: questionary.md - - rich: rich.md - - Ruamel YAML: coding/python/ruamel_yaml.md - - Selenium: selenium.md - - Streamlit: streamlit.md - - SQLAlchemy: coding/python/sqlalchemy.md - - sqlite3: sqlite3.md - - Redis-py: coding/python/redis-py.md - - Requests: requests.md - - Requests-mock: coding/python/requests_mock.md - - Rq: coding/python/rq.md - - python_systemd: python_systemd.md - - sh: python_sh.md - - Talkey: talkey.md - - Tenacity: tenacity.md - - TinyDB: coding/python/tinydb.md - - Torch: torch.md - - Typer: typer.md - - Yoyo: coding/python/yoyo.md - - Type Hints: coding/python/type_hints.md - - Logging: python_logging.md - - Code Styling: coding/python/python_code_styling.md - - Docstrings: coding/python/docstrings.md - - Properties: python_properties.md - - Protocols: python_protocols.md - - Package Management: - - python_package_management.md - - PDM: pdm.md - - pipx: pipx.md - - Pipenv: pipenv.md - - Poetry: python_poetry.md - - Lazy loading: lazy_loading.md - - Plugin System: python_plugin_system.md - - Profiling: python_profiling.md - - Optimization: python_optimization.md - - Anti-Patterns: coding/python/python_anti_patterns.md - - Pytest: - - coding/python/pytest.md - - Parametrized testing: coding/python/pytest_parametrized_testing.md - - Pytest-cases: coding/python/pytest_cases.md - - Pytest-HttpServer: pytest_httpserver.md - - Pytest-xprocess: pytest-xprocess.md - - Internationalization: python_internationalization.md - - Python Snippets: coding/python/python_snippets.md - - Data Classes: coding/python/data_classes.md - - Vue.js: - - vuejs.md - - Vue snippets: vue_snippets.md - - Vuetify: vuetify.md - - Development tools: - - Cypress: cypress.md - - Vite: vite.md - - Vitest: vitest.md - - Bash: - - Bash snippets: bash_snippets.md - - Bash testing: bats.md - - lua: lua.md - - JSON: coding/json/json.md - - SQL: coding/sql/sql.md - - SQLite: sqlite.md - - YAML: coding/yaml/yaml.md - - Promql: coding/promql/promql.md - - Logql: logql.md - - HTML: html.md - - CSS: css.md - - Javascript: - - coding/javascript/javascript.md - - Javascript snippets: javascript_snippets.md - - MermaidJS: mermaidjs.md - - Latex: latex.md - - Graphql: graphql.md - - Qwik: qwik.md - - nodejs: linux/nodejs.md - - JWT: devops/jwt.md - - React: coding/react/react.md - - Coding tools: - - IDES: - - Vim: - - vim.md - - Vim configuration: - - vim_config.md - - Vim Keymaps: vim_keymaps.md - - Vim Package Manager: - - vim_plugin_managers.md - - LazyVim: lazyvim.md - - Packer: vim_packer.md - - UI management configuration: - - Vim foldings: vim_foldings.md - - Vim movement: vim_movement.md - - Tabs vs Buffers: vim_tabs.md - - File management configuration: - - NeoTree: neotree.md - - Telescope: telescope.md - - fzf.nvim: fzf_nvim.md - - Editing specific configuration: - - vim_editor_plugins.md - - Vim formatters: vim_formatters.md - - Vim autocomplete: vim_completion.md - - Vim markdown: vim_markdown.md - - Vim spelling: vim_spelling.md - - Vim autosave: vim_autosave.md - - Coding specific configuration: - - vim_coding_plugins.md - - Treesitter: vim_treesitter.md - - LSP: vim_lsp.md - - Snippets: luasnip.md - - DAP: vim_dap.md - - Git management configuration: - - vim_git.md - - Diffview: diffview.md - - gitsigns: gitsigns.md - - Testing management configuration: vim_testing.md - - Email management: vim_email.md - - Other Vim Plugins: - - linux/vim/vim_plugins.md - - Vim Snippets: vim_snippets.md - - Vim Troubleshooting: vim_troubleshooting.md - - Neovim Plugin Development: vim_plugin_development.md - - Vi vs Vim vs Neovim: vim_vs_neovim.md - - Tridactyl: tridactyl.md - - VSCodium: vscodium.md - - Coding with AI: ai_coding.md - - Git: - - git.md - - Github cli: gh.md - - Forgejo: forgejo.md - - Gitea: gitea.md - - Radicle: radicle.md - - Data orchestrators: - - data_orchestrators.md - - Kestra: kestra.md - - memorious: memorious.md - - Scrapers: - - morph.io: morph_io.md - - ETL: - - Singer: singer.md - - Espanso: espanso.md - - Generic Coding Practices: - - How to code: how_to_code.md - - Program Versioning: - - versioning.md - - Semantic Versioning: semantic_versioning.md - - Calendar Versioning: calendar_versioning.md - - Use warnings to evolve your code: use_warnings.md - - Keep a Changelog: changelog.md - - Writing good documentation: documentation.md - - Conventional comments: conventional_comments.md - - TDD: coding/tdd.md - - GitOps: gitops.md - - Abstract Syntax Trees: abstract_syntax_trees.md - - Software Architecture: - - SOLID: architecture/solid.md - - Domain Driven Design: - - architecture/domain_driven_design.md - - Repository Pattern: architecture/repository_pattern.md - - Service Layer Pattern: architecture/service_layer_pattern.md - - Architecture Decision Record: adr.md - - Database Architecture: architecture/database_architecture.md - - ORM, Query Builder or Raw SQL: architecture/orm_builder_query_or_raw_sql.md - - Microservices: architecture/microservices.md - - Restful APIS: architecture/restful_apis.md - - OCR: - - Table parsing: - - Camelot: camelot.md - - Frontend Development: frontend_development.md - - Park programming: park_programming.md - - Sponsor: sponsor.md - - Issues: issues.md - - DevSecOps: - - devops/devops.md - - Infrastructure as Code: - - Helm: - - devops/helm/helm.md - - Helm Installation: devops/helm/helm_installation.md - - Helm Commands: devops/helm/helm_commands.md - - Helm Secrets: devops/helm/helm_secrets.md - - Helm Git: helm_git.md - - Helmfile: devops/helmfile.md - - Terraform: terraform.md - - Ansible: - - Ansible Snippets: ansible_snippets.md - - Molecule: molecule.md - - Nix: nix.md - - Dotfiles: - - dotfiles.md - - Home Manager: home-manager.md - - Chezmoi: chezmoi.md - - Dotdrop: dotdrop.md - - Infrastructure Solutions: - - Kubernetes: - - devops/kubernetes/kubernetes.md - - Architecture: devops/kubernetes/kubernetes_architecture.md - - Resources: - - Namespaces: devops/kubernetes/kubernetes_namespaces.md - - Pods: devops/kubernetes/kubernetes_pods.md - - ReplicaSets: devops/kubernetes/kubernetes_replicasets.md - - Deployments: devops/kubernetes/kubernetes_deployments.md - - Horizontal Pod Autoscaling: &amp;gt;- - devops/kubernetes/kubernetes_hpa.md - - Volumes: devops/kubernetes/kubernetes_volumes.md - - Services: devops/kubernetes/kubernetes_services.md - - Labels: devops/kubernetes/kubernetes_labels.md - - Annotations: devops/kubernetes/kubernetes_annotations.md - - Ingress: devops/kubernetes/kubernetes_ingress.md - - Jobs: devops/kubernetes/kubernetes_jobs.md - - Kubectl: - - devops/kubectl/kubectl.md - - Kubectl Installation: devops/kubectl/kubectl_installation.md - - Kubectl Commands: devops/kubectl/kubectl_commands.md - - Additional Components: - - Metrics Server: devops/kubernetes/kubernetes_metric_server.md - - Ingress Controller: &amp;gt;- - devops/kubernetes/kubernetes_ingress_controller.md - - External DNS: devops/kubernetes/kubernetes_external_dns.md - - Cluster Autoscaler: &amp;gt;- - devops/kubernetes/kubernetes_cluster_autoscaler.md - - Dashboard: devops/kubernetes/kubernetes_dashboard.md - - Storage Driver: devops/kubernetes/kubernetes_storage_driver.md - - Vertical Pod Autoscaler: &amp;gt;- - devops/kubernetes/kubernetes_vertical_pod_autoscaler.md - - Networking: devops/kubernetes/kubernetes_networking.md - - Debugging: kubernetes_debugging.md - - Backups: - - Velero: velero.md - - Operators: devops/kubernetes/kubernetes_operators.md - - Tools: - - devops/kubernetes/kubernetes_tools.md - - Krew: krew.md - - Ksniff: ksniff.md - - Mizu: mizu.md - - AWS: - - devops/aws/aws.md - - AWS Snippets: aws_snippets.md - - AWS Savings plan: aws_savings_plan.md - - Security groups workflow: devops/aws/security_groups.md - - EKS: devops/aws/eks.md - - EFS: efs.md - - IAM: - - devops/aws/iam/iam.md - - IAM Commands: devops/aws/iam/iam_commands.md - - IAM Debugging: devops/aws/iam/iam_debug.md - - S3: devops/aws/s3.md - - WAF: aws_waf.md + - Instance sizing analysis: devops/prometheus/instance_sizing_analysis.md + - Prometheus Troubleshooting: &amp;gt;- + devops/prometheus/prometheus_troubleshooting.md + - Grafana: grafana.md + - Log analysis: + - Loki: + - loki.md + - Logcli: logcli.md + - Promtail: promtail.md + - Graylog: graylog.md + - Elastic Security: elastic_security.md + - SIEM: siem.md - Databases: - - Redis: architecture/redis.md - - RabbitMQ: rabbitmq.md - - Continuous Deployment: - - ArgoCD: argocd.md - - Continuous Integration: - - devops/ci.md - - Drone: drone.md - - Linters: - - Alex: devops/alex.md - - Flakeheaven: flakeheaven.md - - Flake8: devops/flake8.md - - Markdownlint: devops/markdownlint.md - - Proselint: devops/proselint.md - - Shellcheck: shellcheck.md - - Yamllint: devops/yamllint.md - - Write Good: devops/write_good.md - - Formatters/Fixers: - - Black: devops/black.md - - Yamlfix: yamlfix.md - - Pyment: pyment.md - - mdformat: mdformat.md - - Type Checkers: - - Mypy: devops/mypy.md - - Security Checkers: - - pip-audit: pip_audit.md - - Bandit: devops/bandit.md - - Safety: devops/safety.md - - Dependency managers: - - Pip-tools: devops/pip_tools.md - - Automating Processes: - - copier: copier.md - - cookiecutter: linux/cookiecutter.md - - cruft: linux/cruft.md - - renovate: renovate.md - - letsencrypt: letsencrypt.md - - Threat modeling: - - Privacy threat modeling: privacy_threat_modeling.md - - Storage: - - storage.md - - NAS: nas.md - - OpenZFS: - - linux/zfs.md - - OpenZFS storage planning: zfs_storage_planning.md - - Sanoid: sanoid.md - - ZFS Prometheus exporter: zfs_exporter.md - - Hard drive health: - - hard_drive_health.md - - Smartctl: smartctl.md - - badblocks: badblocks.md - - Resilience: - - linux_resilience.md - - Memtest: memtest.md - - watchdog: watchdog.md - - Magic keys: magic_keys.md - - Monitoring: - - Monitoring Comparison: monitoring_comparison.md - - Prometheus: - - devops/prometheus/prometheus.md - - Architecture: devops/prometheus/prometheus_architecture.md - - Prometheus Operator: devops/prometheus/prometheus_operator.md - - Prometheus Install: devops/prometheus/prometheus_installation.md - - AlertManager: devops/prometheus/alertmanager.md - - Blackbox Exporter: devops/prometheus/blackbox_exporter.md - - cAdvisor: cadvisor.md - - Elasticsearch Exporter: elasticsearch_exporter.md - - Node Exporter: devops/prometheus/node_exporter.md - - Process Exporter: process_exporter.md - - Python Prometheus: python-prometheus.md - - Instance sizing analysis: devops/prometheus/instance_sizing_analysis.md - - Prometheus Troubleshooting: &amp;gt;- - devops/prometheus/prometheus_troubleshooting.md - - Grafana: grafana.md - - Log analysis: - - Loki: - - loki.md - - Logcli: logcli.md - - Promtail: promtail.md - - Graylog: graylog.md - - Elastic Security: elastic_security.md - - SIEM: siem.md - - Databases: - - PostgreSQL: - - postgres.md - - Postgres operators: - - postgres_operators.md - - Zalando Postgres operator: zalando_postgres_operator.md - - elasticsearch: linux/elasticsearch.md - - Oracle Database: oracle_database.md - - Authentication: - - Authentik: authentik.md - - API Management: - - devops/api_management.md - - Kong: devops/kong/kong.md - - Scrum: - - scrum.md - - Templates: - - Refinement Template: refinement_template.md - - Hardware: - - CPU: cpu.md - - RAM: - - ram.md - - ECC RAM: - - ecc.md - - rasdaemon: rasdaemon.md - - Power Supply Unit: psu.md - - GPU: gpu.md - - Pedal PC: pedal_pc.md - - Pentesting: pentesting.md - - Operating Systems: - - Linux: - - linux.md - - Linux Snippets: linux_snippets.md - - Distros: - - Libreelec: libreelec.md - - Tails: tails.md - - Recovery tools: - - finnix: finnix.md - - Security tools: - - fail2ban: linux/fail2ban.md - - pass: pass.md - - Wireshark: wireshark.md - - Canary tokens: canary_tokens.md + - PostgreSQL: + - postgres.md + - Postgres operators: + - postgres_operators.md + - Zalando Postgres operator: zalando_postgres_operator.md + - elasticsearch: linux/elasticsearch.md + - Oracle Database: oracle_database.md + - Authentication: + - Authentik: authentik.md + - API Management: + - devops/api_management.md + - Kong: devops/kong/kong.md + - Scrum: + - scrum.md + - Templates: + - Refinement Template: refinement_template.md + - Hardware: + - CPU: cpu.md + - RAM: + - ram.md + - ECC RAM: + - ecc.md + - rasdaemon: rasdaemon.md + - Power Supply Unit: psu.md + - GPU: gpu.md + - Pedal PC: pedal_pc.md + - Pentesting: pentesting.md + - Operating Systems: + - Linux: + - linux.md + - Linux Snippets: linux_snippets.md + - Distros: + - Libreelec: libreelec.md + - Tails: tails.md + - Recovery tools: + - finnix: finnix.md + - Security tools: + - fail2ban: linux/fail2ban.md + - pass: pass.md + - Wireshark: wireshark.md + - Canary tokens: canary_tokens.md&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Sysadmin tools:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;brew: linux/brew.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;detox: detox.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Docker: docker.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Watchtower: watchtower.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Dynamic DNS: dynamicdns.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;goaccess: goaccess.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Gotify: gotify.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;HAProxy: linux/haproxy.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;journald: journald.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;LUKS: linux/luks/luks.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Outrun: outrun.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;rm: linux/rm.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;sed: sed.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Syncthing: linux/syncthing.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Tahoe-LAFS: tahoe.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Wake on Lan: wake_on_lan.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Wireguard:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;linux/wireguard.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;wg-easy: wg-easy.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;yq: yq.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;zip: linux/zip.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Window manager tools:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;dunst: dunst.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;ferdium: ferdium.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;i3wm: i3wm.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;rofi: rofi.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;User tools:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Browsers:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;google chrome: linux/google_chrome.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Chromium: chromium.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Hushboard: husboard.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Peek: peek.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Terminals:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;terminal_comparison.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Alacritty: alacritty.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Wezterm: wezterm.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Kitty: kitty.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Instant messaging apps:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Delta Chat: deltachat.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Simplex Chat: simplexchat.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Sysadmin tools:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;brew: linux/brew.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;detox: detox.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Docker: docker.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Watchtower: watchtower.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Dynamic DNS: dynamicdns.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;goaccess: goaccess.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Gotify: gotify.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;HAProxy: linux/haproxy.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;journald: journald.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;LUKS: linux/luks/luks.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Outrun: outrun.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;rm: linux/rm.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;sed: sed.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Syncthing: linux/syncthing.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Tahoe-LAFS: tahoe.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Wake on Lan: wake_on_lan.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Wireguard:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;linux/wireguard.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;wg-easy: wg-easy.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;yq: yq.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;zip: linux/zip.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Window manager tools:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;dunst: dunst.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;ferdium: ferdium.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;i3wm: i3wm.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;rofi: rofi.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;User tools:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Browsers:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;google chrome: linux/google_chrome.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Chromium: chromium.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Hushboard: husboard.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Peek: peek.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Terminals:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;terminal_comparison.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Alacritty: alacritty.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Wezterm: wezterm.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Kitty: kitty.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Instant messaging apps:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Delta Chat: deltachat.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Simplex Chat: simplexchat.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Android:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Android Tips: android_tips.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;OS:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;GrapheneOS: grapheneos.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;FuriOS: furios.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Apps:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Cone: cone.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;GadgetBridge: gadgetbridge.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;LibreTube: libretube.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;HappyCow: happycow.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;ICSx5: icsx5.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Orgzly: orgzly.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;OsmAnd: osmand.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Seedvault: seedvault.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Android SDK Platform tools: android_sdk.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Android:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Android Tips: android_tips.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;OS:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;GrapheneOS: grapheneos.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;FuriOS: furios.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Apps:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Cone: cone.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;GadgetBridge: gadgetbridge.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;LibreTube: libretube.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;HappyCow: happycow.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;ICSx5: icsx5.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Orgzly: orgzly.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;OsmAnd: osmand.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Seedvault: seedvault.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Android SDK Platform tools: android_sdk.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Hardware:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Redox: redox.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Vial: vial.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Rock64: rock64.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Filosofía:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;filosofía.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Amor: amor.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Arts:&lt;ul&gt; &lt;li&gt;Writing:&lt;ul&gt; &lt;li&gt;writing/writing.md @@ -746,9 +755,6 @@ nav:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Calistenia: calistenia.md&lt;/li&gt; &lt;li&gt;Aerial Silk: aerial_silk.md&lt;/li&gt; &lt;li&gt;Meditation: meditation.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Maker:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Redox: redox.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Vial: vial.md&lt;/li&gt; &lt;li&gt;Sudokus: sudokus.md&lt;/li&gt; &lt;li&gt;Drawing:&lt;ul&gt; &lt;li&gt;drawing/drawing.md @@ -811,6 +817,7 @@ nav:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Board Games:&lt;ul&gt; &lt;li&gt;board_games.md&lt;/li&gt; &lt;li&gt;Regicide: regicide.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Monologues: monologues.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Projects: projects.md&lt;/li&gt; &lt;li&gt;Contact: contact.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;hardware&#34;&gt;Hardware&lt;/h3&gt; &lt;h4 id=&#34;kobo&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/kobo/&#34;&gt;Kobo&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/kobo/#kobo-forma-suddenly-drains-battery-in-days&#34;&gt;Kobo Forma suddenly drains battery in days.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The solution was to a factory restore, disconnect the wifi and detect which ebook is being the problem.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Some of the user suggestions&lt;/strong&gt; - My battery started doing this many 3 times now. Every time it was a certain book. The first time was something I downloaded from the kobo store, I removed my recent batch of downloads and it was fine (still not sure which is the offending book tbh). The next two were sideloaded borrowbox books. I think its something to do with a download not being downloaded correctly/having all the correct information. The kobos system tries to keep getting the information it wants but fails and keeps doing this in a cycle causing it to drain the battery&lt;/p&gt; &lt;ul&gt; &lt;li&gt;I haven&#39;t bought any new books lately, but I&#39;ve been reading a ton of library books. About when the battery drain started, I had returned a few books directly from the Kobo, instead of doing it on my phone in the Libby app. That&#39;s got to be the problem.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;I disabled the wifi, turned off my Kobo, turned it back on, then restarted the wifi, BUT I did it in Settings, instead of with the quick toggle at the top of the Home screen (when you touch the wifi signal strength indicator). It took longer for the wifi to fully connect than it had all the times I&#39;ve tried this over the last week. Then I did a Sync, which went through quickly.&lt;/p&gt; &lt;p&gt;It&#39;s been 8+ hours, and my Kobo is still at 89%, which is where it was when I started the process!&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;i did find out that it wasn&#39;t going to sleep or powering off if I just closed the cover anymore. It will sleep/ power off if the cover is not closed. I haven&#39;t changed any settings so I&#39;m not sure why this started happening. I&#39;ve had to power it off manually before closing the cover to make sure there is no battery drain.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Basically, the Forma will either go to sleep on its own or I&#39;ll put it to sleep and the battery is at some reasonable amount. Usually overnight, but once while it was sitting on the desk next to me for about an hour, the battery will drain down to nothing. It will shut all the way down and sometimes display the warning that it needs charging. Other times, I don&#39;t even get that warning.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.reddit.com/r/kobo/comments/13npudr/45_year_old_kobo_forma_suddenly_drains_battery_in/&#34;&gt;https://www.reddit.com/r/kobo/comments/13npudr/45_year_old_kobo_forma_suddenly_drains_battery_in/&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.mobileread.com/forums/showthread.php?t=351513&#34;&gt;https://www.mobileread.com/forums/showthread.php?t=351513&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://bugs.launchpad.net/calibre/+bug/1829422&#34;&gt;https://bugs.launchpad.net/calibre/+bug/1829422&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;rock64&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/rock64/&#34;&gt;Rock64&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Install Debian in a rock64.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://wiki.pine64.org/wiki/ROCK64_Software_Releases#Debian&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Go to &lt;a href=&#34;https://wiki.pine64.org/wiki/ROCK64_Software_Releases#Debian&#34;&gt;the rock64 wiki page&lt;/a&gt; to get the download directory for the debian version you want to install&lt;/li&gt; &lt;li&gt;Download &lt;code&gt;firmware.rock64-rk3328.img.gz&lt;/code&gt; and &lt;code&gt;partition.img.gz&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Combine the 2 parts into 1 image file: &lt;code&gt;zcat firmware.rock64-rk3328.img.gz partition.img.gz &amp;gt; debian-installer.img&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Write the created .img file to microSD card or eMMC Module using dd: &lt;code&gt;dd if=debian-installer.img of=/dev/sda bs=4M&lt;/code&gt;. Replace &lt;code&gt;/dev/sda&lt;/code&gt; with your target drive.&lt;/li&gt; &lt;li&gt;Plug the microSD/eMMC card in the Rock64 (and connect a serial console, or keyboard and monitor) and boot up to start the Debian Installer&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Notes:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;An Ethernet connection is required for the above installer&lt;/li&gt; &lt;li&gt;Remember to leave some space before your first partition for u-boot! You can do this by creating a 32M size unused partition at the start of the device.&lt;/li&gt; &lt;li&gt;Auto creating all partitions does not work. You can use the following manual partition scheme:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt; #1 - 34MB  Unused/Free Space
 #2 - 512MB ext2 /boot           (Remember to set the bootable flag)
 #3 - xxGB  ext4 /               (This can be as large as you want. You can also create separate partitions for /home /var /tmp)
 #4 - 1GB   swap                 (May not be a good idea if using an SD card)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;software-tools&#34;&gt;Software tools&lt;/h3&gt; &lt;h4 id=&#34;autorandr&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/autorandr/&#34;&gt;autorandr&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce autorandr.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/phillipberndt/autorandr&#34;&gt;autorandr&lt;/a&gt; is a command line tool to automatically select a display configuration based on connected devices.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;autorandr
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Save your current display configuration and setup with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;autorandr&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--save&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mobile
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Connect an additional display, configure your setup and save it:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;autorandr&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--save&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docked
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Now autorandr can detect which hardware setup is active:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;autorandr
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;mobile
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;docked&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;detected&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To automatically reload your setup:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;autorandr&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--change
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To manually load a profile:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;autorandr&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--load&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;profile&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;or simply:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;autorandr&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;profile&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;liberaforms&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/liberaforms/&#34;&gt;Liberaforms&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Usage of liberaforms.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Marked true&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you are a forms admin you can mark the answers which can be used to for example state that those have been checked and are not trolls, the user can then edit the answers through the magic link but it&#39;s not very probable that it becomes a trollo&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Send edit email&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you want the users to receive an email with the magic link so that they can edit their answers you need to add a &#34;Short text&#34; field of type &#34;Email&#34; and then in the Options you need to enable the setting to send the users the magic link&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Extract the results through API&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Each form at the bottom of the Options tab has a section of API endpoints, once enabled you can extract them with curl:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;BASE_URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;https://forms.komun.org
&lt;span class=&#34;nv&#34;&gt;form_id&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;478&lt;/span&gt;
curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-sqH&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Authorization: Bearer &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;JWT_TOKEN&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;BASE_URL&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/api/form/&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;form_id&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/answers&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;That will give you an answer similar to:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;answers&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;created&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;2025-04-25T15:05:02.384121&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;data&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;radio-group-1712945984567&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Hitzaldia--Charla--Xerrada&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;radio-group-1713092876455&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;55&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;radio-group-1713373271313&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Castellano_1&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;radio-group-1713382758036&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Si_1&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;radio-group-1744968040362-0&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;d8b35c755d9d41e2a844a344ae2494d6&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;text-1712945594310&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Historia de la criptograf\u00eda&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;text-1712945631444&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;text-1712945663611&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;user&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;text-1712947404812&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;user@sindominio.net&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;text-1744967213162-0&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Divulgativa&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;text-1744967571620-0&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Ninguno&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;textarea-1712945646944&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Aproximaci\u00f3n hist\u00f3rica a la criptograf\u00eda, desde la Antig\u00fcedad a d\u00eda de hoy&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;textarea-1712945755946&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;textarea-1712945806547&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;HDMI&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;textarea-1712945865865&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Privacidad, criptograf\u00eda, matem\u00e1ticas, historia&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;textarea-1713380502724&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;form&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;478&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;id&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;36148&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;marked&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;meta&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;err&#34;&gt;``&lt;/span&gt;

&lt;span class=&#34;err&#34;&gt;As&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;you&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;ca&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;see&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;he&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;ields&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;have&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;weird&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;na&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;mes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;ge&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;he&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;de&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;ta&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;ils&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;each&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;ield&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;you&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;ca&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;do&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;he&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;same&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;reques&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;bu&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;`$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;BASE_URL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;/api/&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;orm/$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;orm_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nstea&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;`$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;BASE_URL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;/api/&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;orm/$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;orm_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;/a&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;ns&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;wers`&lt;/span&gt;

&lt;span class=&#34;err&#34;&gt;```jso&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;n&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;form&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;created&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;2025-04-25T11:45:43.633038&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;introduction_md&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;# Call4Nodes Hackmeeting 2025&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;slug&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;call4nodes-hackmeeting-2025-cas&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;structure&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;className&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;form-control&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;label&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;T\u00edtulo&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;text-1712945594310&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;required&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;subtype&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;text&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;type&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;text&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;className&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;form-control&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;label&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Descripci\u00f3n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;textarea-1712945646944&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;required&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;type&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;textarea&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;filosofia&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/filosof%C3%ADa/&#34;&gt;Filosofía&lt;/a&gt;&lt;/h2&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/filosof%C3%ADa/#pensamientos-sueltos&#34;&gt;Pensamientos sueltos.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;En el episodio de &lt;a href=&#34;https://www.ivoox.com/en/ver-al-otro-narrativa-democracia-audios-mp3_rf_146744850_1.html&#34;&gt;Ver al otro: narrativa y democracia&lt;/a&gt; de punzadas sonoras hacen un análisis muy interesante sobre cómo la literatura puede ser un mecanismo muy potente de transformación social.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/filosof%C3%ADa/#pensamientos-sueltos&#34;&gt;Pensamientos sueltos.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Cómo transformar&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.ivoox.com/en/ver-al-otro-narrativa-democracia-audios-mp3_rf_146744850_1.html&#34;&gt;Punzadas Sonoras: Ver al otro: narrativa y democracia&lt;/a&gt;: cómo la literatura puede ser un mecanismo muy potente de transformación social.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://traffic.megaphone.fm/PMSL3439441041.mp3?updated=1748445535&#34;&gt;Punzadas Sonoras: Límite: lugar de enunciación&lt;/a&gt;: El límite como elemento transformador&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Deseo&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.ivoox.com/deseo-tiempos-tinder-pensando-fuerte-audios-mp3_rf_148986477_1.html&#34;&gt;Carne Cruda - PROGRAMAS: El deseo en tiempos de Tinder&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Otros&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://traffic.megaphone.fm/PMSL3665741609.mp3?updated=1749652341&#34;&gt;Punzadas Sonoras: Artesano y artista: desnaturalizar la distinción&lt;/a&gt;: Capítulo super interesante para analizar las dinámicas de poder en el mundo laboral, el concepto de &lt;em&gt;mingei&lt;/em&gt;, pensar sobre &#34;el arte de programar&#34;, ...&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Recomiendan dos libros interesantes:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;La belleza del objeto cotidiano - Soetsu Yanagi&lt;/li&gt; &lt;li&gt;Costumbres en común - E. P. Thompson&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://traffic.megaphone.fm/PMSL7390189795.mp3?updated=1718881108&#34;&gt;Punzadas Sonoras: Matar al Autor: el destino del texto&lt;/a&gt;: No infantilizar al receptor&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/filosof%C3%ADa/#tiempo&#34;&gt;Nuevos capítulos relevantes sobre el tiempo y otras cosas.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://traffic.megaphone.fm/PMSL8763758424.mp3?updated=1712825949&#34;&gt;Punzadas Sonoras: Mirar atrás: un gesto íntimo&lt;/a&gt;: Ruptura de la concepción lineal del tiempo, aplicado entre otras cosas a las relaciones. Hablan también sobre el artículo de &lt;a href=&#34;https://www.publico.es/opinion/tribunas/te-gusto.html&#34;&gt;Leonor Cervantes, Ya no te gusto como antes&lt;/a&gt; que da una perspectiva muy chula sobre las relaciones.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://traffic.megaphone.fm/PMSL3665741609.mp3?updated=1749652341&#34;&gt;Punzadas Sonoras: Artesano y artista: desnaturalizar la distinción&lt;/a&gt;: Capítulo super interesante para analizar las dinámicas de poder en el mundo laboral, el concepto de &lt;em&gt;mingei&lt;/em&gt;, pensar sobre &#34;el arte de programar&#34;, ...&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://traffic.megaphone.fm/PMSL2682413261.mp3?updated=1713967606&#34;&gt;Punzadas Sonoras: El ritmo del habitar con Blanca Lacasa&lt;/a&gt;: Filosofando sobre la casa, en especial sobre la cocina como jaula y reino. También sobre la relación entre madres e hijas&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;amor&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/amor/&#34;&gt;Amor&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/amor/#amor-no-correspondido&#34;&gt;Amor no correspondido.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;En el episodio &lt;a href=&#34;https://www.ivoox.com/en/amor-no-correspondido-por-que-audios-mp3_rf_145889043_1.html&#34;&gt;Amor no correspondido: ¿Por qué?&lt;/a&gt; de punzadas sonoras hacen un análisis muy interesante. Puedes escucharlo directamente desde &lt;a href=&#34;https://traffic.megaphone.fm/PMSL2043145084.mp3?updated=1745962804&#34;&gt;aquí&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;arts&#34;&gt;Arts&lt;/h2&gt; &lt;h3 id=&#34;cooking&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/cooking/&#34;&gt;Cooking&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/cooking/#instrumentos-de-cocina&#34;&gt;Instrumentos de cocina.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=cBnIIHEtjQM&#34;&gt;cómo usar las sartenes de acero inoxidable&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;cooking-basics&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/cooking_basics/&#34;&gt;Cooking Basics&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/cooking_basics/#cortar-una-cebolla&#34;&gt;Todos los cortes para una cebolla.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Picada&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Dividir la cebolla por la raiz&lt;/li&gt; &lt;li&gt;apoyar cada mitad en la tabla con la raiz en perpendicular a ti&lt;/li&gt; &lt;li&gt;cortes grandes perpendicular a la raiz&lt;/li&gt; &lt;li&gt;poner la raiz en tu dirección&lt;/li&gt; &lt;li&gt;cortes grandes paralelos a la tabla&lt;/li&gt; &lt;li&gt;cortes grandes perpendiculares a la tabla&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Juliana&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Dividir la cebolla por la raiz&lt;/li&gt; &lt;li&gt;apoyar cada mitad en la tabla con la raiz en paralelo a ti&lt;/li&gt; &lt;li&gt;cortes al gusto de grosor perpendiculares a la tabla&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Media luna&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Dividir la cebolla por la raiz&lt;/li&gt; &lt;li&gt;apoyar cada mitad en la tabla con la raiz en perpendicular a ti&lt;/li&gt; &lt;li&gt;cortes al gusto de grosor perpendiculares a la tabla&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Brunoise&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Dividir la cebolla por la raiz&lt;/li&gt; &lt;li&gt;apoyar cada mitad en la tabla con la raiz en paralelo a ti&lt;/li&gt; &lt;li&gt;cortes al gusto de grosor perpendiculares a la tabla sin llegar hasta el final&lt;/li&gt; &lt;li&gt;poner la raiz en perpendicular&lt;/li&gt; &lt;li&gt;cortes al gusto de grosor paralelos a la tabla sin llegar hasta el final&lt;/li&gt; &lt;li&gt;cortes al gusto de grosor perpendiculares a la tabla&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Discos&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Sin dividir la cebolla, poner la raiz paralela a la tabla y en perpendicular a ti&lt;/li&gt; &lt;li&gt;cortes al gusto de grosor perpendiculares a la tabla&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Aros&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Corte de discos&lt;/li&gt; &lt;li&gt;desmontar los discos&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;calistenia&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/calistenia/&#34;&gt;Calistenia&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce calistenia.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Técnica básica&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Dominadas&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=3nSaIugxv7Y&#34;&gt;Video tutorial de jéssica martín&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Referencias&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Vídeos&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;+- &lt;a href=&#34;https://www.youtube.com/@jessmartinm&#34;&gt;Jéssica Martín Moreno&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/calistenia/#sentadilla-búlgara&#34;&gt;Sentadilla búlgara.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Hay bastante diversidad de opiniones: &lt;a href=&#34;https://www.youtube.com/watch?v=x_k90ghjPPw&amp;amp;t=225&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;https://www.youtube.com/watch?v=SkNsa3eBwLA&amp;amp;t=116&#34;&gt;2&lt;/a&gt;, &lt;a href=&#34;https://www.youtube.com/watch?v=fSyiHxm1Igw&amp;amp;t=208&#34;&gt;3&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/calistenia/#vídeos&#34;&gt;Añadir vídeos de Cris heria.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://inv.nadeko.net/search?q=Cris%20heria&#34;&gt;Cris Heria&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/calistenia/#shrimp-squat-vs-pistol-squat&#34;&gt;Shrimp squat vs pistol squat.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://gmb.io/shrimp-squats-vs-pistol-squats/&#34;&gt;https://gmb.io/shrimp-squats-vs-pistol-squats/&lt;/a&gt; &lt;a href=&#34;https://www.reddit.com/r/bodyweightfitness/comments/5loylk/pistol_squats_vs_shrimp_squats/&#34;&gt;https://www.reddit.com/r/bodyweightfitness/comments/5loylk/pistol_squats_vs_shrimp_squats/&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/calistenia/#nordic-curl&#34;&gt;Nordic curl.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;languages&#34;&gt;Languages&lt;/h2&gt; &lt;h3 id=&#34;galego&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/galego/&#34;&gt;Galego&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Descubrimiento de os arquivos da meiga.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.osarquivosdameiga.com/&#34;&gt;Os arquivos da meiga&lt;/a&gt;: Foro de contenido en galego&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;esperanto&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/esperanto/&#34;&gt;Esperanto&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce esperanto.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Personal notes on the 38C3 Esperanto gathering&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The language has 130 years&lt;/li&gt; &lt;li&gt;It&#39;s difficult to reform: There is no defined process to change the language and they don&#39;t like newbies to propose changes although there is an academy of esperanto&lt;/li&gt; &lt;li&gt;There are no different past, conditional tenses&lt;/li&gt; &lt;li&gt;There is no conjugation, they always use the pronouns&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Anki decks&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;There is &lt;a href=&#34;https://esperanto.cards/&#34;&gt;this nice deck&lt;/a&gt; also available from the &lt;a href=&#34;https://ankiweb.net/shared/info/353142617&#34;&gt;ankiweb site&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/c3esperanto/kurseto&#34;&gt;38c3 workshop slides&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;science&#34;&gt;Science&lt;/h2&gt; &lt;h3 id=&#34;artificial-intelligence&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/ai/&#34;&gt;Artificial Intelligence&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ai/#ai-and-ecologism&#34;&gt;Add 38C3 talk on AI and ecologism.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://media.ccc.de/v/38c3-resource-consumption-of-ai-degrow-or-die&#34;&gt;38C3 talk: Resource Consumption of AI - Degrow or Die&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;ocr&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/ocr/&#34;&gt;OCR&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add ocr references.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.reddit.com/r/LocalLLaMA/comments/1javx8d/what_is_the_best_llm_based_ocr_open_source/&#34;&gt;What is the best LLM based OCR open source available now? &lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add deekseek ocr tool.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/Bogdanovich77/DeekSeek-OCR---Dockerized-API&#34;&gt;DeekSeek-OCR&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;text-to-speech&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/text_to_speech/&#34;&gt;Text to speech&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/text_to_speech/#references&#34;&gt;Add link to Exploring the World of Open-Source Text-to-Speech Models article.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.bentoml.com/blog/exploring-the-world-of-open-source-text-to-speech-models&#34;&gt;Exploring the World of Open-Source Text-to-Speech Models&lt;/a&gt; diff --git a/docs/vim_plugin_development.md b/docs/vim_plugin_development.md index 8b70311a61..1fa882233a 100644 --- a/docs/vim_plugin_development.md +++ b/docs/vim_plugin_development.md feat(vim_plugin_development): Explain how to load a plugin in a local directory with lazy&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;You can manually edit those files to develop new feature or fix issues on the plugins. Or if you&#39;re developing them in a directory you can specify the &lt;code&gt;dir&lt;/code&gt; directive in the lazy loading.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;birding&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/birding/&#34;&gt;Birding&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce android apps for birding.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;whoBIRD&lt;/li&gt; &lt;li&gt;Merlin Bird ID: I&#39;ve seen it working and it&#39;s amazing, I&#39;m however trying first whoBIRD as it&#39;s in F-droid&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;brain-food&#34;&gt;Brain food&lt;/h2&gt; &lt;h3 id=&#34;galas&#34;&gt;Galas&lt;/h3&gt; &lt;h4 id=&#34;galas-2025&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/galas_2025/&#34;&gt;Galas 2025&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Añadir las galas de 2025.&lt;/p&gt; &lt;p&gt;Los premios al mejor contenido de 2025.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;#mejores-libros-de-2025&#34;&gt;Mejores libros de 2025&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#mejores-series-de-2025&#34;&gt;Mejores series de 2025&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#mejores-películas-de-2025&#34;&gt;Mejores películas de 2025&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#mejores-podcasts-de-2025&#34;&gt;Mejores podcasts de 2025&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#mejores-videojuegos-de-2025&#34;&gt;Mejores videojuegos de 2025&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Mejores libros de 2025&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;#tratise-on-efficacy-de-françois-jullien&#34;&gt;Treatise on efficacy de François Jullien&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#el-deseo-según-gilles-deleuze-de-maite-larrauri&#34;&gt;El deseo según Gilles Deleuze de Maite Larrauri&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#looking-backward,-2000-1887-de-edward-bellamy&#34;&gt;Looking Backward, 2000-1887 de Edward Bellamy&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;** Transformadores**&lt;/p&gt; &lt;p&gt;Qué hacen un crack dentro de ti que te transforma&lt;/p&gt; &lt;p&gt;&lt;strong&gt;# Treatise on efficacy de François Jullien&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/treatise_on_efficacy.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 2004&lt;/li&gt; &lt;li&gt;género: filosofía&lt;/li&gt; &lt;li&gt;longitud: 211 páginas&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Mi libro favorito del año sin duda. Lo he leído 2 veces y media. Mucho subrayado, muchas notas al margen. Es uno de esos libros que te dan unas nuevas gafas para ver el mundo de otra forma.&lt;/p&gt; &lt;p&gt;Ha transformado completamente mi concepción del tiempo, la eficacia, eficiencia, acción, transformación, oportunidad, ...&lt;/p&gt; &lt;p&gt;Eso si, es lectura densa, pero muy muy recomendable.&lt;/p&gt; &lt;p&gt;Me encanta el puente que nos regala Jullien del pensamiento chino vivido y entendido desde la experiencia de ojos europeos.&lt;/p&gt; &lt;p&gt;** El deseo según Gilles Deleuze de Maite Larrauri**&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/deseo_deleuze.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 2000&lt;/li&gt; &lt;li&gt;género: filosofía&lt;/li&gt; &lt;li&gt;longitud: 94 páginas&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Lo \&#34;leí\&#34; cómo nunca antes había leído un libro, simplemente maravilloso. Después lo he leído otras 2 veces.&lt;/p&gt; &lt;p&gt;Maite hace accesible a profanos conceptos clave de Deleuze sobre el deseo.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Capitalismo libidinal&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/capitalismo_libidinal.gif&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 2024&lt;/li&gt; &lt;li&gt;género: filosofía&lt;/li&gt; &lt;li&gt;longitud: 224 páginas&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Libro maravilloso que me abrió la mente a otra concepción del tiempo y del deseo.&lt;/p&gt; &lt;p&gt;La vida se ha hecho mercado. Como si fuese nuestra segunda naturaleza, nos movemos en Uber, viajamos con Airbnb, ligamos en Tinder, compramos en Glovo, nos entretenemos en Netflix, hablamos de nosotros mismos en el lenguaje del capital humano.&lt;/p&gt; &lt;p&gt;Esta segunda naturaleza, que Amador Fernández-Savater llama capitalismo libidinal, nos promete la felicidad, pero lo que produce realmente es sufrimiento y malestar, en forma de precariedad, endeudamiento y dolor psíquico. Paradójicamente, la derecha parece hoy más eficaz que nadie para canalizar esa desesperación y su fuerza de rechazo (Trump, Bolsonaro, Milei), mientras que las estrategias de comunicación y las políticas de contención de la izquierda se muestran insuficientes.&lt;/p&gt; &lt;p&gt;¿Es posible reapropiarnos de nuestro malestar como energía de transformación social? Será necesario aprender a escuchar y hablar el lenguaje del cuerpo, imaginar y activar políticas del deseo.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Utopía no es una isla de Layla Martínez&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/utopia_no_es_una_isla.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 2020&lt;/li&gt; &lt;li&gt;género: ensayo&lt;/li&gt; &lt;li&gt;longitud: 212 páginas&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Una guía de vida, lo he vuelto a leer después de 3 o 4 años. Este libro fue el que me dio las energías para volver a militar tras un largo periodo de hartazgo y desilusión. También me abrió en su momento el camino a buscar la utopía.&lt;/p&gt; &lt;p&gt;El libro te atrapa y es un viaje maravilloso.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;The Life-Changing Magic of Tidying Up de Marie Kondo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/kondo.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2014&lt;/li&gt; &lt;li&gt;género: autoayuda&lt;/li&gt; &lt;li&gt;longitud: 231 páginas&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Me pilló en la mudanza y de nuevo quitando toda la mierda capitalista y las grilladas japas, tiene ideas de trasfondo muy interesantes.&lt;/p&gt; &lt;p&gt;Japanese cleaning consultant Marie Kondo takes tidying to a whole new level, promising that if you properly simplify and organize your house once, you&#39;ll never have to do it again. Most methods advocate a room-by-room approach, which doom you to pick away at your piles of stuff forever. The KonMari Method, with its revolutionary category-by-category system, leads to lasting results. In fact, none of Kondo&#39;s clients have lapsed (and she still has a three-month wait list).&lt;/p&gt; &lt;p&gt;With detailed guidance for determining which items in your house \&#34;spark joy\&#34; (and which don\&#39;t), this international best-seller featuring Tokyo\&#39;s newest lifestyle phenomenon will help you clear your clutter and enjoy the unique magic of a tidy home - and the calm, motivated mindset it can inspire.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;The Bullet Journal method de Ryder Carroll&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/bullet_journal.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2018&lt;/li&gt; &lt;li&gt;género: autoayuda&lt;/li&gt; &lt;li&gt;longitud: 320 páginas&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Un libro que me ha dado muchísimas ideas, pero para disfrutarlo tienes que ser capaz de obviar toda la mierda que lo rodea: su speech sobre su vida típico de libro de autoayuda, su enfoque belicista épico, horrenda visión individualista de que somos culpables de nuestras situaciones y que sólo nosotros podemos arreglarlas con una salida individual.&lt;/p&gt; &lt;p&gt;For years, Ryder Carroll tried countless organizing systems, online and off, but none of them fit the way his mind worked. Out of sheer necessity, he developed a method called the Bullet Journal that helped him become consistently focused and effective. When he started sharing his system with friends who faced similar challenges, it went viral. Just a few years later, to his astonishment, Bullet Journaling is a global movement. The Bullet Journal Method is about much more than organizing your notes and to-do lists. It\&#39;s about what Carroll calls \&#34;intentional living\&#34;: weeding out distractions and focusing your time and energy in pursuit of what\&#39;s truly meaningful, in both your work and your personal life. It\&#39;s about spending more time with what you care about, by working on fewer things. Carroll wrote this book for frustrated list-makers, overwhelmed multitaskers, and creatives who need some structure. Whether you\&#39;ve used a Bullet Journal for years or have never seen one before, The Bullet Journal Method will help you go from passenger to pilot of your own life.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Unf*ck Your Habitat de Rachel Hoffman&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/unfuck_habitat.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2017&lt;/li&gt; &lt;li&gt;género: autoayuda&lt;/li&gt; &lt;li&gt;longitud: 256 páginas&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Impresionantes&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Looking Backward, 2000-1887 de Edward Bellamy&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/looking_backward.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 1888!!&lt;/li&gt; &lt;li&gt;género: novela, sci-fy&lt;/li&gt; &lt;li&gt;longitud: 276 páginas&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Ha despertado en mi sentimientos e ideas como no lo ha hecho un libro en mucho tiempo. Sobretodo la sorpresa de que mucho de la actualidad es realmente muy antigua.&lt;/p&gt; &lt;p&gt;Empecé leyéndolo en inglés pero no me enteraba de nada. El estilo tampoco me estaba enganchando. Hasta que descubrí que se escribió en el 1888!!! También ayuda a entender aquellas cosas que rechinan, como hablar sólo \&#34;del hombre\&#34;.&lt;/p&gt; &lt;p&gt;Es impresionante y triste que ya imagina ideas socialistas aún inalcanzables que me siguen emocionando aún en 2025...&lt;/p&gt; &lt;p&gt;Flipo con la perspectiva feminista de los cuidados, la visión del trabajo, el antipunitivismo (imaginaba ya un mundo sin cárceles) ya en 1888. Me sorprende que habla de desahucios en masa, fraudes millonarios, especulaciones con productos de primera necesidad. Luego tiene ciertos campos en los que es un poco mas meh: la sanidad pública está un poco retrasada, la parte romántica es horrenda, es bastante clasista y tecnócrata. Y es muy curioso a la par que gracioso, con todo los avances que ha sido capaz de imaginar, que no pudiese ver el final de la religión.&lt;/p&gt; &lt;p&gt;El flipe se me relajó cuando vi que el manifiesto comunista se había escrito 40 años antes. Y luego vino el efecto rebote. En vez de ser una lectura inspiradora, que también, me está entrando un poco de desesperación por la mierda de mundo que me está tocando vivir, lo lejos que estamos de un mundo bello de vivir, y a la velocidad a la que nos estamos alejando&lt;/p&gt; &lt;p&gt;Es una bonita crónica del despertar comunista cuando se te cae la venda de los ojos. Apaga la tele, enciende la mente. En el paseo por el barrio pobre hace una bonita descripción del quitar la venda de la deshumanización del pobre como vía de acabar con dicha opresión.&lt;/p&gt; &lt;p&gt;Me ha gustado mucho el final y el tierno epílogo, se mascaba la revolución rusa ya en el 1888 Qué pena que el capitalismo saliese victorioso... Dónde estaríamos ahora si no...&lt;/p&gt; &lt;p&gt;A man being put into a hypnotic sleep, is awakened 113 years later to an entirely new social structure.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Entretenidos&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Un pasatiempos agradable. Para días tontos.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Ñu de Pau luque&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/nu.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2024&lt;/li&gt; &lt;li&gt;género: filosofía&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Pau tiene una curiosa manera de filosofar, más cercana a la gente.Se lee muy bien, te ríes bastante a menudo. Eso si, no tiene un sólo capítulo, y eso hace que sea muy jodido dejar de leerlo.&lt;/p&gt; &lt;p&gt;Me hace mucha gracia Curiel, pienso que me gustaría conocerla pero luego pienso, que menudo vértigo!&lt;/p&gt; &lt;p&gt;«Lo más sospechoso de las soluciones es que se las encuentra siempre que se quiere.» Esta frase de Rafael Sánchez Ferlosio abre un libro excepcional, tan brillante como inclasificable. Entre el relato, la autobiografía y el ensayo filosófico, Pau Luque convoca una galería de personajes extravagantes y tiernos para pensar con ellos la incertidumbre que caracteriza a toda existencia humana: bellos italianos de oficio desconocido, boxeadores frustrados, adolescentes con dentaduras caóticas, poetas clandestinas, émulos de san Ignacio de Loyola, filósofos abrumados por las cuestiones prácticas más triviales o swingers confundidos vagan y divagan por las calles de Barcelona, Génova, Ciudad de México o Vilafranca del Penedès. Son criaturas mugrientas y deslumbrantes que se enfrentan a problemas cotidianos pero también trascendentales.&lt;/p&gt; &lt;p&gt;Frente a las soluciones simples (el ñu que se suele utilizar en los crucigramas en español para rellenar huecos --casi un chiste entre los aficionados--) y a las recetas de manual, Pau Luque hace una loa a los secretos, los equívocos, los errores e incluso las contradicciones. Ñu es un iluminador libro de antiayuda.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;We have always lived in the castle de Shirley Jackson&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/lived_in_the_castle.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 1962&lt;/li&gt; &lt;li&gt;género: novela, drama&lt;/li&gt; &lt;li&gt;longitud: 187 páginas&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Recomendado por Layla Martinez, autora de utopía no es una isla y carcoma, el estilo ne recuerda mucho a Aury en the slow regard of silent things.&lt;/p&gt; &lt;p&gt;La casa tiene mucha presencia como en carcoma. Al principio hubo un momento que casi lo dejo, pero me alegro de haberlo acabado.&lt;/p&gt; &lt;p&gt;El estilo es curioso y agradable de leer, me cuadra que le guste a layla.&lt;/p&gt; &lt;p&gt;Shirley Jackson\&#39;s beloved gothic tale of a peculiar girl named Merricat and her family\&#39;s dark secret&lt;/p&gt; &lt;p&gt;Taking readers deep into a labyrinth of dark neurosis, We Have Always Lived in the Castle is a deliciously unsettling novel about a perverse, isolated, and possibly murderous family and the struggle that ensues when a cousin arrives at their estate.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Una belleza terrible de Edurne Portela&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/belleza_terrible.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2025&lt;/li&gt; &lt;li&gt;género: novela histórica&lt;/li&gt; &lt;li&gt;longitud: 335 páginas&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Una mirada novelada a la historia de mujeres troskistas. Al final engancha pero me costaron un poco ciertas partes.&lt;/p&gt; &lt;p&gt;Algunos pensamientos que fui apuntando mientras lo leía:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Ay qué ilusión me dio ver que había sacado un nuevo libro. Al leer la descripción no me pude contener y empecé a dar palmadas y emitir ruidos nerviosos.&lt;/li&gt; &lt;li&gt;Ya lo tengo entre mis manos, huele bien, como todos los de gutenberg.&lt;/li&gt; &lt;li&gt;El primer capítulo me encanta, no solo leo su obra sino que encima la acompaño en esta aventura. Me recuerda un poco a su reflexión con maddie y las fronteras pero está vez está acompañada y la reflexión es más madura. Debe ser que Maddie le dio fuerzas. Al decir que compartía casa con jose ovejero me puse a buscar como loco si eran pareja, y luego pensé, qué más da!&lt;/li&gt; &lt;li&gt;De nuevo, como en sus otros libros, el estilo de la escritura te atrapa, ay qué bien tener estas 300 páginas por delante.&lt;/li&gt; &lt;li&gt;Me gusta cómo se centra en las historias de ellas incluso cuando están rodeadas de peña tan importante&lt;/li&gt; &lt;li&gt;Me gusta mucho su filosofía de escritura, el imaginar sobre el inventar incluso a costa de potencial novelístico. Creo que tiene mucho más fuerza y es mucho más respetuosa por las historias verdaderas que intentan representar.&lt;/li&gt; &lt;li&gt;Sus finales que siempre son maravillosos Ganas de comentarla con henar, caps y rosa&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;A Deadly Education de Naomi Novik&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/deadly_education.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2020&lt;/li&gt; &lt;li&gt;género: novela fantasía mágica&lt;/li&gt; &lt;li&gt;longitud: 320 páginas&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Crea un mundo muy interesante, es como un harry potter más oscuro.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Mejores series de 2025&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Este 2025 mis series favoritas han sido:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;a href=&#34;#say-nothing&#34;&gt;Say nothing&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#adolescencia&#34;&gt;Adolescencia&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#animal&#34;&gt;Animal&lt;/a&gt;&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;strong&gt;Impactantes&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Contenido original, que deja su huella.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Say nothing&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/say_nothing.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 2024&lt;/li&gt; &lt;li&gt;género: drama&lt;/li&gt; &lt;li&gt;longitud: 9 episodios&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Ambientada a lo largo de toda la historia del IRA, es interesante que no cuentan la versión de los vencedores, sin dejar de ser crítica con los vencidos. Me sorprendieron mucho los paralelismos con ETA.&lt;/p&gt; &lt;p&gt;Cada capítulo es una joya. Probablemente la mejor serie que he visto en 2025.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Adolescencia&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/adolescencia.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 2024&lt;/li&gt; &lt;li&gt;género: drama, crimen&lt;/li&gt; &lt;li&gt;longitud: 4 episodios largos e intensos&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Serie que engancha muy fuertemente, que nos hace reflexionar sobre la relación adulto - joven, el papel de la tecnología y a donde tiende el mundo.&lt;/p&gt; &lt;p&gt;Creo que es una serie que deberían de ver todos los padres y madres con sus hijes, también en los institutos. Creo que se podrían generar unos debates muy ricos.&lt;/p&gt; &lt;p&gt;El formato también es muy especial. La grabación contínua hace que la acción no te deje un respiro. Yo pensaba que el formato de grabación contínua lo conseguían haciendo cortes y uniéndolo con efectos gráficos, pero no. Cada capítulo está grabado de un tirón, y si se equivocan, a empezar de nuevo. Flipo.&lt;/p&gt; &lt;p&gt;Cómo actua todo el reparto es impresionante.&lt;/p&gt; &lt;p&gt;El único pero que le pongo es que sólo muestra una visión muy pesimista de la juventud, en la que es fácil caer en la desesperación de que no tienen remedio y nos vamos al carajo. Que aunque es cierto, también hay otra gran cantidad de jóvenes que vienen pisando con mucha fuerza sobre los que podríamos aprender mucho.&lt;/p&gt; &lt;p&gt;El mundo de una familia se pone patas arriba cuando Jamie Miller, de 13 años, es arrestado y acusado de asesinar a una compañera de clase. Los cargos contra su hijo les obliga a enfrentarse a la peor pesadilla de cualquier padre.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Tiernas&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Contenido de domingo noche, aquel que te abraza, que es calentito, en el que los personajes se convierten parte de tu familia.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Doctor en Alaska&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/doctor_en_alaska.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 1990&lt;/li&gt; &lt;li&gt;género: comedia, drama, fantasía&lt;/li&gt; &lt;li&gt;longitud: 110 episodios&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Zona de comfort absoluta que ha envejecido genial. Después de verla hace unos años, he revisitado capítulos sueltos con la familia. Si no la has visto es un acompañamiento bueno para el invierno.&lt;/p&gt; &lt;p&gt;Joel Fleishman es un médico recién licenciado. Debido a una cláusula de la letra pequeña del contrato de su beca acaba en la remota y descaradamente extraña ciudad de Cicely (Alaska). Cordialmente bienvenido por el fundador de Cicely, Maurice Minnifield, antiguo astronauta de la NASA, y por el resto de la peña de inadaptados y excéntricos que forma el vecindario, Joel descubre que es cada vez más difícil abandonar la ciudad a la que inconscientemente ha llegado. Todo se complica por la presencia de Maggie O&#39;Connell, alcaldesa de Cicely y piloto de la localidad, una mujer hermosa pero completamente independiente; ambientado todo ello por el musical y filosófico programa de radio presentado por Chris en la KBHR.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Graciosas&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Contenido que arranca carcajadas&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Animal S01&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/animal.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 2025&lt;/li&gt; &lt;li&gt;género: comedia&lt;/li&gt; &lt;li&gt;longitud: 9 episodios&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;La serie más graciosa que he visto en el año. Carcajada tras carcajada, la retranca gallega en todo su explendor. Mais unha pena que non fose en galego :(&lt;/p&gt; &lt;p&gt;Antón, un veterinario sin un duro, acepta trabajar en una tienda de mascotas de lujo y pasa de cuidar animales en el campo a vender cucaditas y caprichos para perros mimados.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;División Palermo S02&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/division_palermo.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2025&lt;/li&gt; &lt;li&gt;género: comedia&lt;/li&gt; &lt;li&gt;longitud: 6 episodios&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Quizá es por la pérdida de novedad, pero no me reí tanto como con la primera. Aun así tiene muchos puntos muy muy graciosos.&lt;/p&gt; &lt;p&gt;Una Guardia Urbana inclusiva, ideada como operación de marketing para mejorar la imagen de las fuerzas de seguridad, descubrirá algo que no debía y se enfrentará con unos extraños narcos.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;The Bear S03&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/the_bear.jpeg&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2024&lt;/li&gt; &lt;li&gt;género: comedia, drama&lt;/li&gt; &lt;li&gt;longitud: 6 episodios&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Su majestad S01&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/su_majestad.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2025&lt;/li&gt; &lt;li&gt;género: comedia&lt;/li&gt; &lt;li&gt;longitud: 7 episodios&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Me la vi casi del tirón en un momento de bajona anímica. Es muy divertido cómo se mete con los borbones, pero duele que consigue que al final empatices con ella. Maldito cine.&lt;/p&gt; &lt;p&gt;Cuando se ve salpicado por un escándalo financiero, el rey Alfonso XIV decide apartarse de la primera línea pública durante unos meses. Pero alguien debe quedarse al frente de la institución. No hay más alternativa que su única hija, Pilar. Ahora la princesa tendrá que demostrarle al país que no es la irresponsable, vaga e inútil que todos creen. Lo que pasa es que igual tienen razón.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Entretenidas&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Un pasatiempos agradable. Para días tontos.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Detective Touré&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/toure.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2024&lt;/li&gt; &lt;li&gt;género: comedia, misterio&lt;/li&gt; &lt;li&gt;longitud: 6 episodios&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Es bastante divertida y está genial cómo meten el contenido político&lt;/p&gt; &lt;p&gt;Touré, un inmigrante guineano asentado en Bilbao, se gana la vida como improvisado detective de poca monta. Su pericia, intuición y particular sentido del humor le hacen ganarse la confianza de la Ertzaintza y le sumergen en una compleja investigación en la que se enfrentará a múltiples peligros: conocerá de cerca la corrupción inmobiliaria, los tejemanejes del conflictivo barrio de San Francisco e incluso se topará con la mafia nigeriana.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Andor S02&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/andor.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2025&lt;/li&gt; &lt;li&gt;género: comedia, crímen&lt;/li&gt; &lt;li&gt;longitud: 12 episodios&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;No le llega a la suela del zapato de la primera temporada (que si no has visto, merece mucho la pena). Pero sigue siendo entretenida, empieza flojilla y va ganando con los episodios.&lt;/p&gt; &lt;p&gt;Son bonitos los guiños a Palestina&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Eric&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/eric.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2025&lt;/li&gt; &lt;li&gt;género: drama, misterio&lt;/li&gt; &lt;li&gt;longitud: 6 episodios&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Un padre desesperado y un tenaz policía luchan contra sus propios demonios en la Nueva York de los años 80 mientras buscan a su hijo de nueve años, que ha desaparecido.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;La residencia S01&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/la_residencia.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2025&lt;/li&gt; &lt;li&gt;género: comedia, crímen&lt;/li&gt; &lt;li&gt;longitud: 8 episodios&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Empieza un poco flojilla pero con el tiempo va mejorando.&lt;/p&gt; &lt;p&gt;Una excéntrica y brillante inspectora investiga un crimen en la Casa Blanca, donde todos los empleados e invitados a la cena de Estado esconden un secreto y podrían ser el asesino.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Mejores películas de 2025&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Este año mis películas favoritas han sido:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;a href=&#34;#arsénico-por-compasion&#34;&gt;Arsénico por compasión&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#coco&#34;&gt;Coco&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#el-gran-dictador&#34;&gt;El gran dictador&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#barrio&#34;&gt;Barrio&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#tiempos-modernos&#34;&gt;Tiempos modernos&lt;/a&gt;&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;Es curioso cómo ha pesado el cine antíguo frente al moderno.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Transformadoras&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Barrio&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/barrio.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 1998&lt;/li&gt; &lt;li&gt;género: drama&lt;/li&gt; &lt;li&gt;longitud: 1h34m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;En uno de esos barrios situados al sur de las grandes ciudades, a los que no llega ni el metro ni el dinero, Javi, Manu y Rai son compañeros de instituto, pero, sobre todo, amigos. Tienen esa edad en la que ni se es hombre ni se es niño, en la que se habla mucho de chicas y muy poco con ellas. Comparten también la vida en el barrio, el calor del verano y un montón de problemas. El primero es el propio barrio, un lugar de grandes bloques de viviendas sociales, de ladrillo oscuro y arquitectura deprimente y depresiva. Allí hay pocas cosas que hacer, y en agosto aún menos. El centro de la ciudad queda lejos y las comunicaciones son malas, así que los tres amigos pasan la mayor parte del tiempo por las calles del barrio.[&lt;/p&gt; &lt;p&gt;&lt;strong&gt;No Other Land&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/no_other_land.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 2024&lt;/li&gt; &lt;li&gt;género: documental&lt;/li&gt; &lt;li&gt;longitud: 1h25m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Podría haber caído tanto en impactante como en transformadora. Una producción muy necesaria tras más de un año de genocidio en Palestina...&lt;/p&gt; &lt;p&gt;Un joven activista palestino documenta durante cinco años los violentos desalojos de palestinos en Cisjordania. Con la colaboración de cineastas israelíes y palestinos, narra la compleja relación que surge entre él y un periodista israelí dispuesto a unirse a su lucha, a pesar de sus diferentes circunstancias. Una obra conmovedora que explora resistencia, empatía y esperanza en un contexto de conflicto.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Cómo tener sexo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/como_tener_sexo.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2023&lt;/li&gt; &lt;li&gt;género: drama&lt;/li&gt; &lt;li&gt;longitud: 1h31m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Película que sería interesante ver con los jóvenes ya sea en casa o en los institutos. Aborda muy bien el tema del consentimiento.&lt;/p&gt; &lt;p&gt;Tres adolescentes británicas se van de vacaciones para celebrar sus ritos de iniciación: beber, salir de fiesta y ligar, en lo que debería ser el mejor verano de sus vidas.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Graciosas&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Contenido que arranca carcajadas.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Arsénico por compasión&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/arsenico_por_compasion.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 1944&lt;/li&gt; &lt;li&gt;género: comedia, crimen&lt;/li&gt; &lt;li&gt;longitud: 1h58m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;La vi dos veces del tirón en una semana, me parece una obra maestra. Siento que ya no se hacen comedias como esta. El guión es maravilloso, y la traducción también. Aunque soy un aférrimo defensor de ver las películas en versión original, esta recomendaría verla en castellano.&lt;/p&gt; &lt;p&gt;Un crítico teatral que acaba de casarse decide visitar a sus ancianas tías antes de marcharse de luna de miel. Durante la visita descubrirá que las encantadoras viejecitas tienen una manera muy peculiar de practicar la caridad.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;El gran dictador&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/el_gran_dictador.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 1940&lt;/li&gt; &lt;li&gt;género: comedia, bélica&lt;/li&gt; &lt;li&gt;longitud: 2h05m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;El discurso final es memorable.&lt;/p&gt; &lt;p&gt;Un humilde barbero judío tiene un parecido asombroso con el dictador de la nación Tomania, que promete sacar adelante y que culpa a los judíos de la situación del país. El dictador ataca al país fronterizo, pero es confundido con el barbero por sus propios guardias, siendo ingresado en un campo de concentración. Simultáneamente, el pobre barbero es confundido con el dictador...&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Tiempos modernos&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/tiempos_modernos.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 1936&lt;/li&gt; &lt;li&gt;género: comedia, drama, romance&lt;/li&gt; &lt;li&gt;longitud: 1h27m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Es muy triste que sea tan actual...&lt;/p&gt; &lt;p&gt;Extenuado por el frenético ritmo de la cadena de montaje, un obrero metalúrgico acaba perdiendo la razón. Después de recuperarse en un hospital, sale y es encarcelado por participar en una manifestación en la que se encontraba por casualidad. En la cárcel, también sin pretenderlo, ayuda a controlar un motín, gracias a lo cual queda en libertad. Una vez fuera, reemprende la lucha por la supervivencia en compañía de una joven huérfana a la que conoce en la calle.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;El apartamento&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/el_apartamento.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 1960&lt;/li&gt; &lt;li&gt;género: comedia, drama, romance&lt;/li&gt; &lt;li&gt;longitud: 2h05m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Otra comedia impresionante, con crítica social.&lt;/p&gt; &lt;p&gt;C.C. Baxter es un modesto pero ambicioso empleado de una compañía de seguros de Manhattan. Está soltero y vive solo en un discreto apartamento que presta ocasionalmente a sus superiores para sus citas amorosas. Tiene la esperanza de que estos favores le sirvan para mejorar su posición en la empresa. Pero la situación cambia cuando se enamora de una ascensorista que resulta ser la amante de uno de los jefes que usan su apartamento.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;La vida segun Philomena Cunk&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/philomena_cunk.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2024&lt;/li&gt; &lt;li&gt;género: comedia&lt;/li&gt; &lt;li&gt;longitud: 1h10m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Conmovedoras&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Coco&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/coco.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 2017&lt;/li&gt; &lt;li&gt;género: animación, aventura&lt;/li&gt; &lt;li&gt;longitud: 1h49m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Segunda vez que la veo y no pierde. Al principio me dio mucho miedo de lo que podía hacer disney con méxico, pero la verdad es que es una obra de arte.&lt;/p&gt; &lt;p&gt;Un joven aspirante a músico llamado Miguel se embarca en un viaje extraordinario a la mágica tierra de sus ancestros. Allí, el encantador embaucador Héctor se convierte en su inesperado amigo y le ayuda a descubrir los misterios detrás de las historias y tradiciones de su familia.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Entretenidas&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Un pasatiempos agradable. Para días tontos.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;La princesa prometida&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/la_princesa_prometida.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 1987&lt;/li&gt; &lt;li&gt;género: Aventura, comedia, fantasía, romance&lt;/li&gt; &lt;li&gt;longitud: 1h45m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Me resistí mucho tiempo a verla porque tenía miedo que fuese una ñoñería de amor romantico. Que tristemente lo es xD, pero todo lo demás hace que sea una maravilla. Los diálogos, las coreografías, los personajes... Eso si, prepárate para exasperarte ante el papel de princesa objeto inútil.&lt;/p&gt; &lt;p&gt;Me volvió a despertar el sentimiento de \&#34;ya no se hacen películas como estas\&#34;. Tiene un algo que lo despierta (además de la retrogradez machista)&lt;/p&gt; &lt;p&gt;Después de buscar fortuna durante cinco años, Westley retorna a su tierra para casarse con su amada, la bella Buttercup, a la que había jurado amor eterno. Sin embargo, para recuperarla habrá de enfrentarse a Vizzini y sus esbirros. Una vez derrotados éstos, tendrá que superar el peor de los obstáculos: el príncipe Humperdinck pretende desposar a la desdichada Buttercup, pese a que ella no lo ama, ya que sigue enamorada de Westley.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Kneecap&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/kneecap.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 2024&lt;/li&gt; &lt;li&gt;género: Comedia, drama&lt;/li&gt; &lt;li&gt;longitud: 1h45m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Me encanta que sean ellos mismos los que actuan, la historia está muy chula y el grupo mola todo.&lt;/p&gt; &lt;p&gt;En Irlanda hay 80.000 hablantes de irlandés, 6.000 viven en el norte y tres de ellos lo van a poner todo patas arriba cuando formen un trío de rap llamado Kneecap. Anárquicos, salvajes y dispuestos a todo para salvar su lengua materna.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Inside Out 2&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/inside_out_2.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 2024&lt;/li&gt; &lt;li&gt;género: animación, aventura, comedia&lt;/li&gt; &lt;li&gt;longitud: 1h36m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Riley entra en la adolescencia y el Cuartel General de su cabeza sufre una repentina reforma para hacerle hueco a algo totalmente inesperado propio de la pubertad: ¡nuevas emociones! Alegría, Tristeza, Ira, Miedo y Asco, con años de impecable gestión a sus espaldas (según ellos...) no saben muy bien qué sentir cuando aparece con enorme ímpetu Ansiedad. Y no viene sola: le acompañan envidia, vergüenza y aburrimiento.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;El tercer hombre&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/el_tercer_hombre.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 1949&lt;/li&gt; &lt;li&gt;género: misterio, suspense&lt;/li&gt; &lt;li&gt;longitud: 1h44m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Orson Welles es Harry Lime y Joseph Cotten actúa como su amigo de la infancia, Holly Martins, en este clásico thriller de Graham Greene, dirigido por Carol Reed. Martins busca a Lime en la caótica postguerra de Viena, y se encuentra así mismo metido en un entorno de amores, decepción y asesinatos.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Los Rose&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/los_rose.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2025&lt;/li&gt; &lt;li&gt;género: comedia, drama, romance&lt;/li&gt; &lt;li&gt;longitud: 1h45m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;La vida parece fácil para la pareja perfecta que forman Ivy y Theo: carreras de éxito, un matrimonio feliz y unos hijos estupendos. Pero detrás de la fachada de su supuesta vida ideal, se avecina una tormenta: la carrera de Theo se desploma mientras que las ambiciones de Ivy despegan, lo que desencadena una caja de Pandora de competitividad y resentimiento ocultos.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Una historia verdadera&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/una_historia_verdadera.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2025&lt;/li&gt; &lt;li&gt;género: comedia, drama, romance&lt;/li&gt; &lt;li&gt;longitud: 1h45m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Alvin Straight (Richard Farnsworth) es un achacoso anciano que vive en Iowa con una hija discapacitada (Sissy Spacek). Además de sufrir un enfisema y pérdida de visión, tiene graves problemas de cadera que casi le impiden permanecer de pie. Cuando recibe la noticia de que su hermano Lyle (Stanton), con el que está enemistado desde hace diez años, ha sufrido un infarto, a pesar de su precario estado de salud, decide ir a verlo a Wisconsin. Para ello tendrá que recorrer unos 500 kilometros, y lo hace en el único medio de transporte del que dispone: una máquina cortacésped.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;El mago de Oz&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/el_mago_de_oz.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 1939&lt;/li&gt; &lt;li&gt;género: aventura, fantasía&lt;/li&gt; &lt;li&gt;longitud: 1h43m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;La gran evasión&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/la_gran_evasion.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 1963&lt;/li&gt; &lt;li&gt;género: aventura, bélica, drama&lt;/li&gt; &lt;li&gt;longitud: 2h43m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;La quimera del oro&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/la_quimera_del_oro.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 1925&lt;/li&gt; &lt;li&gt;género: aventura, comedia, drama&lt;/li&gt; &lt;li&gt;longitud: 1h35m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Aventuras de un solitario buscador de oro en Alaska, donde se topa con varios personajes rudos, y se enamora de la hermosa Georgia, a la que trata de conquistar.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Mujeres al borde de un ataque de nervios&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/mujeres_al_borde.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 1988&lt;/li&gt; &lt;li&gt;género: comedia, drama&lt;/li&gt; &lt;li&gt;longitud: 1h28m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Pepa e Iván son actores de doblaje. Él es un mujeriego empedernido y, después de una larga relación, rompe con Pepa: le deja un mensaje en el contestador pidiéndole que le prepare una maleta con sus cosas. Al quedarse sola, Pepa no soporta vivir en una casa llena de recuerdos y decide alquilarla. Mientras espera que Iván vaya a recoger la maleta, la casa se le va llenando de gente extravagante de la que aprenderá muchas cosas sobre la soledad y la locura.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Mejores podcasts de 2025&lt;/strong&gt;&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;a href=&#34;#punzadas-sonoras&#34;&gt;Punzadas sonoras&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#quieto-todo-el-mundo&#34;&gt;Quieto todo el mundo&lt;/a&gt;&lt;/li&gt; &lt;li&gt;(de eso no se habla) temporada 2: Se llamaba como yo&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#no-es-el-fin-del-mundo&#34;&gt;No es el fin del mundo&lt;/a&gt;&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://punzadas.com/punzadas-sonoras/&#34;&gt;Punzadas sonoras&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Paula Ducay e Inés García me han recordado la importancia de la Filosofía como nadie. Gracias a ellas he descubierto nuevas maneras de ver, me han regalado palabras que describen a la percepción pensamientos y sensaciones que tengo y gracias a ellas he conseguido esclarecer un poco más mi entendimiento del mundo y de mi mismo. En especial han sido la base para desenterrar pilares imprescindibles de mi vida como son el deambular creativo y la solitud.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/punzadas_sonoras.jpeg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Siento que mi camino con ellas ha sido perfecto, me enamoré de ellas en los derroteros de &lt;a href=&#34;#carne-cruda&#34;&gt;Carne cruda&lt;/a&gt; en 2023. Eran episodios de 20 minutos muy accesibles, y una vez que ya me enganché a ellas, los programas de una hora se hacen cortos.&lt;/p&gt; &lt;p&gt;Escucharlas es un absoluto placer.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.ivoox.com/podcast-quieto-todo-mundo_sq_f11778903_1.html&#34;&gt;Quieto todo el mundo&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Facu Díaz y Miguel Maldonado han conseguido alegrarme las horas de cocina de los lunes con la manera más amable de acercarme desde la comedia a la actualidad política. Hacen un combo maravilloso.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/quieto_todo_el_mundo.jpeg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Con un tono divertido y relajado, en el programa van comentando desde la ignorancia, la improvisación y, en ocasiones, la desidia las noticias más importantes de la semana.&lt;/p&gt; &lt;p&gt;Esta misa roja ha creado una verdadera religión a lo largo de los programas, no sólo por el lore sino por el vacío existencial que dejan esa semana que no publican programa. Especialmente cuando es porque los nazis les ocupan los espacios, asco de pais...&lt;/p&gt; &lt;p&gt;&lt;strong&gt;(de eso no se habla) temporada 3: Se llamaba como yo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;En «De eso no se habla» hablamos de los silencios que crea esa frase, tanto en nosotras como en la sociedad: de las historias que se esconden detrás de ellos, y de qué pasa cuando los rompemos.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/de_eso_no_se_habla.webp&#34;/&gt;&lt;/p&gt; &lt;p&gt;Esta tercera temporada trata sobre la memoria de la niña Begoña Urroz, sobre las cinco décadas de silencio de una familia… Y sobre el ruido que lo rompió. Muestra cómo la guerra sucia del estado contra ETA&lt;/p&gt; &lt;p&gt;&lt;strong&gt;No es el fin del mundo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Una mirada muy interesante a la geopolítica mundial&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/no_es_el_fin_del_mundo.webp&#34;/&gt;&lt;/p&gt; &lt;p&gt;El podcast semanal de El Orden Mundial (EOM) para entender qué pasa en el mundo. Análisis, contexto y matices sobre la realidad internacional. Porque estar al día de qué pasa más allá de nuestras fronteras no debería ser ni complicado ni aburrido.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Mejores videojuegos de 2025&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Mi juego favorito de este año ha sido [&lt;em&gt;Thronefall&lt;/em&gt;]{.spurious-link target=&#34;Thronefall&#34;}&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Thronefall&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/thronefall.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;platforms: linux&lt;/li&gt; &lt;li&gt;year: 2024&lt;/li&gt; &lt;li&gt;genre: Strategy, tactical, puzzle, arcade&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Al principio era un poco escéptico porque tienes unas localizaciones fijas para las torres, pero sigue siendo un juego difícil y entretenido. Además que los gráficos son preciosos.&lt;/p&gt; &lt;p&gt;A minimalist game about building and defending a little kingdom. Thronefall is a classic strategy game without unnecessary complexity, just some healthy hack-and-slay. Build up your base during the day, and defend it &#39;til your last breath at night.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/dragonsweeper/&#34;&gt;Dragonsweeper&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/dragon_sweeper.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;year: 2025&lt;/li&gt; &lt;li&gt;genre: puzzle&lt;/li&gt; &lt;li&gt;platform: desktop, mobile&lt;/li&gt; &lt;li&gt;price: free&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Simple de jugar pero muy adictivo.&lt;/p&gt; &lt;p&gt;A minesweeper game that requires observation by mixing roguelike elements with the classic gameplay.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;You Must Build A Boat&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/you_must_build_a_boat.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;platforms: android, linux&lt;/li&gt; &lt;li&gt;year: 2015&lt;/li&gt; &lt;li&gt;genre: puzzle&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;You Must Build A Boat is the sequel to the award winning \&#34;10000000\&#34;. Travel the world, run procedurally generated dungeons finding artifacts, capturing monsters and recruiting crew for your...&lt;/p&gt; &lt;p&gt;&lt;strong&gt;10000000 {#section-1}&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/1000.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;platforms: android, linux&lt;/li&gt; &lt;li&gt;year: 2012&lt;/li&gt; &lt;li&gt;genre: puzzle&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;10000000 is an award winning hybrid RPG/Action/Puzzle game. Matching tiles controls your character enabling you to explore, fight and loot. When you are not facing monsters you will be back in your prison, constructing buildings and getting stronger for your next run.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;books&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/books/&#34;&gt;Books&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/books/#mejores-libros-del-2024&#34;&gt;Mejores libros del 2024.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;2024 ha sido un año muy potente para mi en cuanto a lectura se refiere,&lt;/p&gt; &lt;p&gt;La mayor parte de los 23 libros que me he terminado han tenido buena puntuación.&lt;/p&gt; &lt;p&gt;5: 8 4: 7 3: 6 2: 1 1: 1&lt;/p&gt; &lt;p&gt;6 se han quedado por el camino y sólamente recuerdo uno que se me haya hecho pesado de leer y me he forzado a terminar de leerlo.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Política&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.todostuslibros.com/libros/mano-dura_978-84-19158-52-9#synopsis&#34;&gt;The global police state by William I. Robinson&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;William ha puesto palabras bonitas y claras a mis pensamientos como no lo hacia un libro desde el manifiesto comunista hace muchos años. Un análisis impoluto sobre la crisis del capitalismo y el mundo al que nos estamos dirigiendo. A la vez que dando una dirección a la que apuntar para combatirlo. Ambiciosa y difícil, pero la que más me cuadra. Me encantaría debatirlo con la gente y lo regalaré allá donde vaya. Da un poco de yuyu porque hasta el final final final no da atisbo de luz al final del túnel tan necesaria en estos tiempos oscuros, pero aguantad, que merece la pena (✿◠‿◠).&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/the_global_police_state.webp&#34;/&gt;&lt;/p&gt; &lt;p&gt;A muchos nos aterra el nuevo auge del fascismo. Solo en Europa, la extrema derecha integra cinco gobiernos y tiene representación parlamentaria destacada en veintisiete países. Pero esto es apenas la punta del iceberg de un proceso bastante más complejo: el auge del Estado policial global como respuesta a la profunda crisis del sistema capitalista actual. A medida que el neoliberalismo dispara las desigualdades hasta límites insospechados (los veintiséis millonarios más importantes del mundo poseen hoy más de la mitad de la riqueza mundial mientras dos mil millones de personas viven en situación de pobreza), los individuos se vuelven «desechables». Una población excedente que supone una amenaza de rebelión para la clase capitalista. Para refrenarla, se hacen ubicuos todo tipo de sistemas de control, rastreos biométricos, encarcelamientos generalizados, barcos‐prisión, violencia policial, persecución de migrantes, represión contra activistas medioambientales, eliminación de prestaciones sociales, desahucios, precarización de las clases medias, guerras estratégicas sustentadas por capital privado... Así, el Estado policial global no remite ya a un mecanismo policial y militar, sino a la propia economía global como totalidad represiva, cuya lógica es tan mercantil como política y cultural. Y, mientras la codicia infinita de la clase dominante hunde al capitalismo en una crisis sin precedentes (llevando la degradación ecológica y el deterioro social a su límite absoluto), el neofascismo afianza su posición en ese Estado policial global cuyo objetivo es la exclusión coercitiva de la humanidad excedente. Basándose en datos estremecedores y argumentos incontrovertibles, William I. Robinson demuestra hasta qué punto el capitalismo del siglo XXI se ha convertido en un sistema absoluto de represión como único método para mantenerse en pie más allá de sus contradicciones terminales, y defiende la urgencia de crear un movimiento que trascienda los meros llamados a la justicia social y ataque a la yugular.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://joyfulmilitancy.com/&#34;&gt;Joyful militancy by carla bergman and Nick Montgomery&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Un libro muy interesante desde todas las perspectivas. Por cómo debió de ser el proceso creativo, por el cuidado y respeto a todos los distintos movimientos que representa, por las personas entrevistadas y las ideas que transmiten... Para mi ha sido un libro clave para una de las transformaciones más importantes de concepto de vida que he dado este año, entrar más en contacto con mi deseo y dejar que este fluya sobre las rigideces autoimpuestas entre otras cosas por el concepto del deber. Esto aplicado a mi vida en general y a mi militancia en particular.&lt;/p&gt; &lt;p&gt;Es cierto que la mayor parte de los conceptos transgresores son heredados del feminismo, pero el libro los refleja muy bien y puede ser un buen punto de entrada para los que no nos hemos zambullido aún muy profundamente en leer teoría feminista.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/joyful.webp&#34;/&gt;&lt;/p&gt; &lt;p&gt;Why do radical movements and spaces sometimes feel laden with fear, anxiety, suspicion, self-righteousness and competition? The authors call this phenomenon rigid radicalism: congealed and toxic ways of relating that have seeped into radical movements, posing as the ‘correct’ way of being radical. In conversation with organizers and intellectuals from a wide variety of currents, the authors explore how rigid radicalism smuggles itself into radical spaces, and how it is being undone. Rather than proposing ready-made solutions, they amplify the questions that are already being asked among movements. Fusing together movement-based perspectives and contemporary affect theory, they trace emergent forms of trust, care and responsibility in a wide variety of radical currents today, including indigenous resurgence, anarchism, transformative justice, and youth liberation. Joyful Militancy foregrounds forms of life in the cracks of Empire, revealing the ways that fierceness, tenderness, curiosity, and commitment can be intertwined.&lt;/p&gt; &lt;p&gt;Interviewees include Silvia Federici, adrienne maree brown, Marina Sitrin, Gustavo Esteva, Tasnim Nathoo, Kian Cham, Leanne Betasamosake Simpson, Sebastian Touza, Walidah Imarisha, Margaret Killjoy, Glen Coulthard, Richard Day, Melanie Matining, Zainab Amadahy and Mik Turje.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://piedrapapellibros.com/producto/verano-sin-vacaciones-las-hijas-de-la-costa-del-sol/&#34;&gt;Verano sin vacaciones. Las hijas de la Costa del Sol por Ana geranios&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Libro que dolorosamente me quitó la venda de los ojos en cuanto al turismo y la restauración. Tiene un formato perfecto, la primera parte (Verano sin vacaciones) te llega a la patata haciéndote vivir en las entrañas lo podrido que está el sector y luego en la segunda (Las hijas de la Costa del Sol) le da forma de ensayo y te llega al coco.&lt;/p&gt; &lt;p&gt;Lo leímos en un club de lectura muy chulo organizado por la Escuela de las Periferias, que junto a Estuve aquí y me acordé de nosotros de Anna Pacheco, nos ayudó a tener unas discusiones super interesantes que terminaron de definir mi nuevo concepto sobre el turismo. Además tuve la suerte de asistir a una mesa redonda impresionante con Ana, Valeria del Sindicato de Inquilinas y dos compas de la PAH que le dieron distintos matices a la problemática de la vivienda que tenemos que sufrir. Y para colmo luego estuvimos rajando en un parque con Ana y luego dimos un paseo por el barrio. Un final maravilloso para un libro fantástico.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/Verano-sin-vacaciones.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;¿Cómo sería un mundo sin hostelería? ¿Es posible pensar en una sociedad en la que ninguna persona tuviera que servir ni ser servida, donde las bandejas no tuvieran ninguna utilidad?&lt;/p&gt; &lt;p&gt;Este libro no va de eso. Es justo lo contrario: el análisis de un sector económico que se enriquece gracias al trabajo de quienes se dedican a servir a un público que puede permitírselo.&lt;/p&gt; &lt;p&gt;Verano sin vacaciones es el diario de una trabajadora del sector hostelero de la costa malagueña; un relato al que se suma Las hijas de la Costa del Sol, un ensayo situado que nos interpela como turistas, pero también nos hace comprender qué hay detrás de una industria que descansa sobre la explotación laboral, el servilismo político y la voracidad ecológica.&lt;/p&gt; &lt;p&gt;El leitmotiv es hacernos preguntas, dialogar, pensar, compartir; imaginarnos, ahora sí, cómo sería un mundo sin hostelería.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://donellameadows.org/systems-thinking-book-sale/&#34;&gt;Thinking in systems by Donella H. Meadows&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Me ha encantado. Al principio dudaba de la autora por no saber de que pie cojeaba pero al final es un libro que abre mentes. Muchas ganas de resumirlo. Al principio del año descubrí el concepto de &lt;a href=&#34;https://en.wikipedia.org/wiki/Systems_thinking&#34;&gt;systems thinking&lt;/a&gt; a way of making sense of the complexity of the world by looking at it in terms of wholes and relationships rather than by splitting it down into its parts. It has been used as a way of exploring and developing effective action in complex contexts, enabling systems change. Systems thinking draws on and contributes to systems theory and the system sciences.&lt;/p&gt; &lt;p&gt;Me maravilló la idea de tener un sistema nuevo y sistemático de analizar el mundo, me encantan los modelos y creo que systems thinking puede llegar a ser muy potente. De los cuatro libros que me leí del tema este es sin duda el mejor.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;&#34;/&gt; This is a primer that brings you to a tangible world where anyone can understand systems and engage with them in meaningful ways. The problems we face – war, hunger, poverty, climate change, racism, gender-based violence cannot be solved by quick fixes in isolation. We need to see the whole system and reach deeper to the structures and mindsets that are at play. Written with a hopeful and visionary tone, Thinking in Systems helps readers overcome confusion and helplessness, which is a first step in the work of change.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Novela&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://edurneportela.com/mejor-la-ausencia/&#34;&gt;Mejor la ausencia de Edurne Portela&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Lo empecé el 6 de marzo y esa noche me leí 209 páginas. A las 5:35 dije que ya era suficiente, aunque me fuese rabia no terminarmelo en un día. Hoy ha caído en la madrugada del 7 al 8 de marzo. Muy icónico todo, ya no me da rabia haberlo acabado hoy. Me ha maravillado, cómo escribe Edurne, es una pasada. Te coje con la primera frase y es tu cuerpo el que suplica que dejes de leer. No hay piedad. El cambio de lenguaje a medida que va avanzando la vida de Amaia es alucinante . Cómo le da un repaso a todo el conflicto de Euskadi visto desde alguien que sin estar dentro está salpicada. No se si tuvo miedo al publicarlo, es bastante crítica con toda la movida. Me sorprende porque ella si que está politizada. He pensado que me gustaría preguntarle su opinión respecto a lo que pasó y como ella lo vivió. He pensado varias veces a lo largo de la novela si es autobiográfica. Es impresionante que sea su primera novela.&lt;/p&gt; &lt;p&gt;Ha sido un año del (no estoy seguro de si bien llamado) conflicto vasco, ya que también leí Las fieras de Clara Usón que también me gustó mucho.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/mejor_la_ausencia.webp&#34;/&gt;&lt;/p&gt; &lt;p&gt;Crecer siempre implica alguna forma de violencia, contra uno mismo o contra aquellos que quieren imponer su autoridad. Cuando además la vida trascurre en un pueblo de la margen izquierda del Nervión durante los años 80 y 90, y todo es heroína, paro, detritus medioambiental, cuando en las calles silban cada semana las pelotas de goma y los gases lacrimógenos y las paredes están llenas de consignas asesinas, la violencia no es sólo un problema personal. Mejor la ausencia nos presenta una familia destruida, atravesada por la violencia de su entorno. Amaia, la pequeña de cuatro hermanos, narra ese entorno brutal desde su mirada de niña y adolescente. Compartimos con ella su miedo, su perplejidad, su rabia, ante un padre que hiere, una madre que se esconde, tres hermanos que, como ella, sólo buscan salir adelante.&lt;/p&gt; &lt;p&gt;Amaia es la joven que se enfrenta, hasta alcanzar sus propios límites, a este mundo hostil. Amaia es también la mujer que años después vuelve a su pueblo para encontrarse con un pasado irresuelto. En ese camino de ida y vuelta, en sus huidas y regresos, descubrirá, a su pesar, que nadie escapa del entorno en el que se cría, de la familia que le toca en suerte. Y que reconocerlo es la única manera de sobrevivir.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;To kill a mockingbird de Harper Lee&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Inglés muy dificil. La historia muy bien contada, es como que todo el pueblo es de la familia. Engancha bastante.&lt;/p&gt; &lt;p&gt;One of the best-loved stories of all time, To Kill a Mockingbird has been translated into more than 40 languages, sold more than 30 million copies worldwide, served as the basis for an enormously popular motion picture, and voted one of the best novels of the 20&lt;sup&gt;th&lt;/sup&gt; century by librarians across the United States. A gripping, heart-wrenching, and wholly remarkable tale of coming-of-age in a South poisoned by virulent prejudice, it views a world of great beauty and savage inequities through the eyes of a young girl, as her father -- a crusading local lawyer -- risks everything to defend a black man unjustly accused of a terrible crime.&lt;/p&gt; &lt;p&gt;Lawyer Atticus Finch defends Tom Robinson -- a black man charged with the rape of a white girl. Writing through the young eyes of Finch&#39;s children Scout and Jem, Harper Lee explores with rich humor and unswerving honesty the irrationality of adult attitudes toward race and class in small-town Alabama during the mid-1930s Depression years. The conscience of a town steeped in prejudice, violence, and hypocrisy is pricked by the stamina and quiet heroism of one man&#39;s struggle for justice. But the weight of history will only tolerate so much.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Gestión del tiempo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.oliverburkeman.com/fourthousandweeks&#34;&gt;Four thousand weeks by Oliver Burkeman&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Me ha encantado. Me flipa encontrar un libro de auto ayuda y time management con una perspectiva bastante anticapitalista. Probablemente es el mejor libro de gestión de tiempo que conozco, ha generado en mi esos momentos preciosos en los que surgen ideas fuera de los límites mentales que tenía antes. Ha sido bastante liberador y ha influido mucho en crear mi nueva manera de entender el tiempo y cómo navegarlo. Lo he utilizado mucho este año para rediseñar todos mis &lt;a href=&#34;roadmap_adjustments.md&#34;&gt;roadmap adjustments&lt;/a&gt;, en especial el trimestral y el anual. Muy muy recomendable.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/4000_weeks.webp&#34;/&gt;&lt;/p&gt; &lt;p&gt;The average human lifespan is absurdly, outrageously, insultingly brief: if you live to 80, you have about four thousand weeks on earth. How should we use them best?&lt;/p&gt; &lt;p&gt;Of course, nobody needs telling that there isn&#39;t enough time. We&#39;re obsessed by our lengthening to-do lists, our overfilled inboxes, the struggle against distraction, and the sense that our attention spans are shrivelling. Yet we rarely make the conscious connection that these problems only trouble us in the first place thanks to the ultimate time-management problem: the challenge of how best to use our four thousand weeks.&lt;/p&gt; &lt;p&gt;Four Thousand Weeks is an uplifting, engrossing and deeply realistic exploration of this problem. Rejecting the futile modern obsession with &#39;getting everything done,&#39; it introduces readers to tools for constructing a meaningful life, showing how the unhelpful ways we&#39;ve come to think about time aren&#39;t inescapable, unchanging truths, but choices we&#39;ve made, as individuals and as a society - and its many revelations will transform the reader&#39;s worldview.&lt;/p&gt; &lt;p&gt;Drawing on the insights of both ancient and contemporary philosophers, psychologists, and spiritual teachers, Oliver Burkeman sets out to realign our relationship with time - and in doing so, to liberate us from its grasp.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://gregmckeown.com/books/essentialism/&#34;&gt;Essentialism: The disciplined pursuit of less&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Me apesta su tono emprendedor de sueño americano y su falta de perspectiva de clase. Eso sumado a su prepotencia mandaloriana de &#34;this is the way&#34;&#34; con el essentialist path y non essentialist path hace que la lectura sea bastante horrenda. Dicho esto, si consigues abstraerte de toda esa mierda, el author aporta conceptos interesantes que me han ayudado mucho a diseñar las revisiones trimestrales y anuales del &lt;a href=&#34;roadmap_adjustments.md&#34;&gt;roadmap adjustments&lt;/a&gt;. Es especialmente interesante para aquellas personas que no sabemos decir que no y acabamos enfrascados en mil movidas.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/essentialism.webp&#34;/&gt;&lt;/p&gt; &lt;p&gt;Essentialism isn&#39;t about getting more done in less time. It&#39;s about getting only the right things done. Have you ever found yourself stretched too thin? Do you simultaneously feel overworked and underutilized? Are you often busy but not productive? Do you feel like your time is constantly being hijacked by other people&#39;s agendas? If you answered yes to any of these, the way out is the Way of the Essentialist. Essentialism is more than a time-management strategy or a productivity technique. It is a systematic discipline for discerning what is absolutely essential, then eliminating everything that is not, so we can make the highest possible contribution toward the things that really matter. By forcing us to apply more selective criteria for what is Essential, the disciplined pursuit of less empowers us to reclaim control of our own choices about where to spend our precious time and energy -- instead of giving others the implicit permission to choose for us. Essentialism is not one more thing. It&#39;s a whole new way of doing everything. It&#39;s about doing less, but better, in every area of our lives.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Ensayo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.librosdelasteroide.com/libro/la-novia-grulla&#34;&gt;La novia grulla de CJ Hauser&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Me ha encantado cómo trata temas tan complicados, su filosofía de vida y lo bien que está escrito. Una ventana a todo tipo de &#34;amor&#34; desde la &#34;nueva&#34; perspectiva feminista. Me entraron muchas ganas de leerlo ya que no paraban de mencionarlo en &lt;a href=&#34;https://lyz-code.github.io/blue-book/podcasts/#punzadas_sonoras&#34;&gt;Punzadas sonoras&lt;/a&gt;, me parece que Paula e Inés me van a dar muy buen material de lectura, aunque no pueda seguirlas el ritmo ni de lejos xD.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/grulla.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Una mirada franca y divertida sobre el amor, la intimidad y la identidad en el siglo XXI.&lt;/p&gt; &lt;p&gt;Diez días después de cancelar su boda, CJ Hauser se embarcó en una expedición a Texas para estudiar a la grulla trompetera. Tras una semana chapoteando en las marismas del golfo comprendió que había estado a punto de firmar un contrato para vivir la vida de otra persona.&lt;/p&gt; &lt;p&gt;¿Qué pasaría si decidiéramos liberarnos de la idea tradicional de felicidad y nos abriéramos a lo inesperado? Hauser se sirve de su propia experiencia para explorar las relaciones sentimentales, los fracasos amorosos, la intimidad y la identidad en el siglo XXI. Disecciona la personalidad de los protagonistas de Expediente X mientras intenta entender qué es el amor, rememora sus peores citas de Tinder, chatea con desconocidos que conversan como robots y analiza a Katharine Hepburn en Historias de Filadelfia para aprender a no perderse en una relación.&lt;/p&gt; &lt;p&gt;Divertido, inclasificable y brutalmente sincero, este libro trata de cómo modelamos nuestra vida sentimental y nuestra comprensión de los demás a través de los relatos; una lectura para aquellos que aprenden a encontrar la alegría en el no saber e intentan, aunque a veces fracasen, construir particulares formas de vida, familia y hogar.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Las dos amigas de Tony Morrison&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Un libro breve, inquietante y curioso que te hace cuestionarte a ti mismo. Me gustaría dar una reflexión más larga pero es imposible no meter spoilers. Cuando te lo leas lo hablamos :P&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;podcasts&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/podcasts/&#34;&gt;Podcasts&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/podcasts/#mejores-podcasts-de-2024&#34;&gt;Mejores podcasts de 2024.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Estoy muy contento porque este año he descubierto podcast muy buenos, hasta el punto de considerar unidireccionalmente a varias de ellas ya parte de mi familia.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.ivoox.com/podcast-quieto-todo-mundo_sq_f11778903_1.html&#34;&gt;Quieto todo el mundo&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Facu Díaz y Miguel Maldonado han conseguido alegrarme las horas de cocina de los lunes con la manera más amable de acercarme desde la comedia a la actualidad política.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/quieto_todo_el_mundo.jpeg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Con un tono divertido y relajado, en el programa van comentando desde la ignorancia, la improvisación y, en ocasiones, la desidia las noticias más importantes de la semana.&lt;/p&gt; &lt;p&gt;Esta misa roja ha creado una verdadera religión a lo largo de los programas, no sólo por el lore sino por el vacío existencial que dejan esa semana que no publican programa. Especialmente cuando es porque los nazis les ocupan los espacios, asco de pais...&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://punzadas.com/punzadas-sonoras/&#34;&gt;Punzadas sonoras&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Paula Ducay e Inés García me han recordado la importancia de la Filosofía como nadie. Gracias a ellas he descubierto nuevas maneras de ver, me han regado palabras que describen a la percepción pensamientos y sensaciones que tengo y gracias con ellas he conseguido esclarecer un poco más mi entendimiento del mundo y de mi mismo. En especial han sido la base para desenterrar pilares imprescindibles de mi vida como son el deambular creativo y la solitud.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/punzadas_sonoras.jpeg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Siento que mi camino con ellas ha sido perfecto, me enamoré de ellas en los derroteros de &lt;a href=&#34;#carne-cruda&#34;&gt;Carne cruda&lt;/a&gt; de la temporada pasada (una pena enorme que no las hayan renovado). Son episodios de 20 minutos muy accesibles, y una vez que ya me enganché a ellas, los programas de una hora se hacen cortos.&lt;/p&gt; &lt;p&gt;Escucharlas es un absoluto placer.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://es.wikipedia.org/wiki/No_hay_negros_en_el_T%C3%ADbet&#34;&gt;No hay negros en el Tibet&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Asaari Bibang, Lamine Thior y Frank T nos regalan un par de veces al mes una ventana a la realidad de ser una persona afrodescendiente en España. Es un podcast muy amable de escuchar, te partes con las puyas que se echan, además de ser super interesante ver el salto generacional que hay entre Frank y (Asaari y Lamine). Eso si, tienes que aprender a vivir con que se interrumpan continuamente. Al principio esto me rayó bastante ya que es especialmente irritante cuando se lo hacen a Asaari. Luego ves que no tienen filtro y no sólo se cortan entre ellas, también lo hacen con las personas invitadas.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;no_hay_negros_en_el_tibet.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Una manera muy fácil de introducir el antiracismo en tu vida ya que con sus relatos eres capaz de verlo, identificártelo, aprender y corregir elementos racistas que tenemos inculcados por este sistema asqueroso. Y creo que como material divulgativo es perfecto ya que lo abordan desde un punto de vista antipunitivista nada agresivo, sin que por ello se dejen títere sin cabeza.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.eldiario.es/carnecruda/&#34;&gt;Carne cruda&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Violeta Muñoz y Javier Gallego han sido la voz seria de la actualidad para mi este año.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/carne_cruda.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Si es cierto que esta temporada estoy un poco más desencantado con el equipo ya que:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Ya no cuentan con Punzadas Sonoras para los derroteros y a Santiago Alba Rico nunca le he tragado.&lt;/li&gt; &lt;li&gt;Hace tiempo que no llaman a Pablo Elorduy del Salto, me encantaba oírle y le echo de menos :(.&lt;/li&gt; &lt;li&gt;Han cambiado el Nido de rojos de la temporada pasada por &#34;A diestra y siniestra&#34; en el que incluyen a peña de derechas en los debates para darle otro punto de vista. Ya se van regulando pero los primeros programas tuve que dejar de escucharlo con cabreo porque tenía que escuchar cosas como que el genocidio de palestina estaba justificado y lindezas similares. Entiendo que puede darle color al debate, pero para eso ya me voy a los medios tradicionales la verdad...&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Aun así sigue siendo el referente para mi para saber qué está pasando tanto en el mundo en general como en el mundo activista.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Muriendo porque saquen más&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Este año hay unos cuantos podcast que no han continuado y que me encantarían que volviesen como:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://deesonosehabla.com/&#34;&gt;(de eso no se habla)&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.soynuriaperez.com/podcast&#34;&gt;Gabinete de curiosidades&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;videogames&#34;&gt;Videogames&lt;/h3&gt; &lt;h4 id=&#34;dragonsweeper&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/dragonsweeper/&#34;&gt;DragonSweeper&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce dragonsweeper.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://danielben.itch.io/dragonsweeper&#34;&gt;DragonSweeper&lt;/a&gt; is an addictive simple RPG-tinged take on the Minesweeper formula. You can &lt;a href=&#34;https://danielben.itch.io/dragonsweeper&#34;&gt;play it for free&lt;/a&gt; in your browser.&lt;/p&gt; &lt;p&gt;If you&#39;re lost at the beginning start reading the &lt;a href=&#34;https://arstechnica.com/gaming/2025/02/dragonsweeper-is-my-favorite-game-of-2025-so-far&#34;&gt;ArsTechnica blog post&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Tips&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Use &lt;code&gt;Shift&lt;/code&gt; to mark numbers you already know.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://danielben.itch.io/dragonsweeper&#34;&gt;Play&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://danielben.itch.io/dragonsweeper&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://arstechnica.com/gaming/2025/02/dragonsweeper-is-my-favorite-game-of-2025-so-far&#34;&gt;ArsTechnica blog post&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;age-of-empires&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/age_of_empires/&#34;&gt;Age of Empires&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: New teutons vs portuguese video.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://piped.video/watch?v=XECeghut_5U&amp;amp;t=0&#34;&gt;Teutons vs Portuguese | 1v1 Arabia | Hera vs MbL&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;board-games&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/board_games/&#34;&gt;Board Games&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/board_games/#cooperative-games&#34;&gt;Add cooperative games references.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.reddit.com/r/boardgames/comments/rih0z3/your_favorite_cooperative_board_games/?tl=es-es&#34;&gt;Favourite coop games&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;monologues&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/monologues/&#34;&gt;Monologues&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add Sammy Obeid.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/@SammyObeidComedy&#34;&gt;Sammy Obeid&lt;/a&gt;: Antizionist comedian&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;aside class=&#34;md-source-file&#34;&gt; &lt;span class=&#34;md-source-file__fact&#34;&gt; &lt;span class=&#34;md-icon&#34; title=&#34;Last update&#34;&gt; &lt;svg viewbox=&#34;0 0 24 24&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z&#34;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt; &lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago&#34; title=&#34;January 1, 2026 07:00:46 UTC&#34;&gt;&lt;span class=&#34;timeago&#34; datetime=&#34;2026-01-01T07:00:46+00:00&#34; locale=&#34;en&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date&#34; title=&#34;January 1, 2026 07:00:46 UTC&#34;&gt;2026-01-01&lt;/span&gt; &lt;/span&gt; &lt;/aside&gt; &lt;/article&gt;</description>
      <link>https://lyz-code.github.io/blue-book/newsletter/2025/</link>
      <pubDate>2026-01-01 07:00:46+00:00</pubDate>
      <source url="https://lyz-code.github.io/blue-book/yearly.xml">The Blue Book</source>
      <guid isPermaLink="true">https://lyz-code.github.io/blue-book/newsletter/2025/</guid>
      
    </item>
    
    <item><title>2024</title>
      <author>Lyz</author>
      <description>&lt;article class=&#34;md-content__inner md-typeset&#34;&gt;  &lt;h2 id=&#34;activism&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/activism/&#34;&gt;Activism&lt;/a&gt;&lt;/h2&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduction to activism.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Activism&#34;&gt;Activism&lt;/a&gt; consists of efforts to promote, impede, direct or intervene in social, political, economic or environmental reform with the desire to make changes in society toward a perceived greater good.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Recomendar el episodio de podcast el diario de Jadiya.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://deesonosehabla.com/episodios/episodio-2-jadiya/&#34;&gt;Diario de Jadiya&lt;/a&gt; (&lt;a href=&#34;https://dts.podtrac.com/redirect.mp3/dovetail.prxu.org/302/7fa33dd2-3f29-48f5-ad96-f6874909d9fb/Master_ep.2_Jadiya.mp3&#34;&gt;link al archivo&lt;/a&gt;): es algo que todo xenófobo debería de escuchar, es un diario de una chavala saharaui que formó parte del programa de veranos en familias españolas.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/anticolonialism/#poems&#34;&gt;Add Rafeef Ziadah pro-palestine poem.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=neYO0kJ-6XQ&#34;&gt;Rafeef Ziadah - &#34;Nosotros enseñamos vida, señor&#34;&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Añadir el vídeo del racismo no se sostiene.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://youtube.com/shorts/5Y7novO2t_c?si=dqMGW4ALFLoXZiw3&#34;&gt;El racismo no se sostiene&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/antitourism/#artículos&#34;&gt;Nuevo artículo contra el turismo.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.elsaltodiario.com/turismo/abolir-turismo&#34;&gt;Abolir el turismo - Escuela de las periferias&lt;/a&gt;: Lleguemos a donde lleguemos, no puede ser que sea más fácil imaginar el fin del capitalismo que el fin del turismo.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;antifascism&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/antifascism/&#34;&gt;Antifascism&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/antifascism/#campañas&#34;&gt;Animaros a colaborar con el Crowdfunding para los 6 de Zaragoza.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.goteo.org/project/libertad-6-de-zaragoza&#34;&gt;Crowdfunding para la libertad de los 6 de Zaragoza&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;hacktivism&#34;&gt;Hacktivism&lt;/h3&gt; &lt;h4 id=&#34;chaos-communication-congress&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/ccc/&#34;&gt;Chaos Communication Congress&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the CCC.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://events.ccc.de/en/&#34;&gt;Chaos Communication Congress&lt;/a&gt; is the best gathering of hacktivism in europe.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Prepare yourself for the congress&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can follow &lt;a href=&#34;https://github.com/MacLemon/CongressChecklist&#34;&gt;MacLemon&#39;s checklist&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://events.ccc.de/congress/2024/hub/de/wiki/apps/&#34;&gt;Install the useful apps&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;The schedule app&lt;/em&gt;&lt;/p&gt; &lt;p&gt;You can use either the Fahrplan app or giggity, I&#39;ve been using the second for a while, so is the one I use&lt;/p&gt; &lt;p&gt;&lt;em&gt;The navigation app&lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;c3nav&lt;/code&gt; is an application to get around the congress. The official F-droid is outdated, so add &lt;a href=&#34;https://f-droid.c3nav.de/fdroid/repo/?fingerprint=C1EC2D062F67A43F87CCF95B8096630285E1B2577DC803A0826539DF6FB4C95D&#34;&gt;their repository&lt;/a&gt; to get the latest version.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt; - [Home](&lt;a href=&#34;https://events.ccc.de/en/&#34;&gt;https://events.ccc.de/en/&lt;/a&gt; - &lt;a href=&#34;https://engel.events.ccc.de/&#34;&gt;Engelsystem&lt;/a&gt; - &lt;a href=&#34;https://engel.events.ccc.de/faq&#34;&gt;Angel FAQ&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ccc/#angel&#39;s-system&#34;&gt;Introduce the Angel&#39;s system.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://angelguide.c3heaven.de/&#34;&gt;Angels&lt;/a&gt; are participants who volunteer to make the event happen. They are neither getting paid for their work nor do they get free admission.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://angelguide.c3heaven.de/#_expectations&#34;&gt;Expectation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Helping at our events also comes with some simple, but important expectations of you:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Be on time for your shift or give Heaven early notice.&lt;/li&gt; &lt;li&gt;Be well rested, sober and not hungry.&lt;/li&gt; &lt;li&gt;Be open-minded and friendly in attitude.&lt;/li&gt; &lt;li&gt;Live our moral values:&lt;/li&gt; &lt;li&gt;Be excellent to each other.&lt;/li&gt; &lt;li&gt;All creatures are welcome.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://angelguide.c3heaven.de/#_quick_start&#34;&gt;Quickstart&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Create yourself an &lt;a href=&#34;https://engel.events.ccc.de/&#34;&gt;Engelsystem account&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Arrive at the venue&lt;/li&gt; &lt;li&gt;Find &lt;a href=&#34;https://c3nav.de/&#34;&gt;the Heaven&lt;/a&gt; and go there.&lt;/li&gt; &lt;li&gt;Talk to a welcome angel or a shift coordinator to get your angel badge and get marked as arrived.&lt;/li&gt; &lt;li&gt;If you have any questions, you can always ask the shift coordinators behind the counter.&lt;/li&gt; &lt;li&gt;Attend an angel meeting&lt;/li&gt; &lt;li&gt;Announced in the Engelsystem news&lt;/li&gt; &lt;li&gt;Click yourself an interesting shift&lt;/li&gt; &lt;li&gt;Read shift descriptions first&lt;/li&gt; &lt;li&gt;Participate in your shift&lt;/li&gt; &lt;li&gt;Use the navigation to find the right place.&lt;/li&gt; &lt;li&gt;Arrive a little bit early at the meeting point&lt;/li&gt; &lt;li&gt;Rest for at least one hour&lt;/li&gt; &lt;li&gt;Repeat from step 5&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;And always, have a lot of fun.&lt;/p&gt; &lt;p&gt;To get more insights read &lt;a href=&#34;https://jascha.wtf/angels-at-chaos-about-volunteering-and-fitting-in/&#34;&gt;this article&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://angelguide.c3heaven.de/#_the_engelsystem&#34;&gt;The engelsystem&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The &lt;a href=&#34;https://engel.events.ccc.de/&#34;&gt;Engelsystem&lt;/a&gt; is the central place to distribute the work to all the helping angels. It can be a bit overwhelming at the beginning but you will get used to it and find your way around.&lt;/p&gt; &lt;p&gt;As you might have seen there are many different shifts and roles for angels — some sounding more appealing than others. There are shifts where you need to have some knowledge before you can take them. This knowledge is given in introduction meetings or by taking an unrestricted shift in the team and getting trained on the job. These introduction meetings are announced in the Engelsystem under the tab &#34;Meetings&#34;. Heaven and the teams try to make sure that there are only restrictions for shifts in place where they are absolutely needed.&lt;/p&gt; &lt;p&gt;Most restrictions really only need a meeting or some unrestricted shifts at the team to get lifted. Harder restrictions are in place where volunteers need to have special certification, get access to certain systems with a huge amount of data (e.g. mail-queues with emails from participants) or handling big piles of money. Usually the requirements for joining an angeltype are included in the description of the angeltype.&lt;/p&gt; &lt;p&gt;Especially the restricted shifts are tempting because after all we want to get the event running, aren’t we? From our personal experience what gets the event running are the most common things: Guarding a door, collecting bottle/trash, washing dishes in the angel kitchen, being on standby to hop in when spontaneous help is needed or check the wrist band at the entrance.&lt;/p&gt; &lt;p&gt;If there are any further questions about angeltypes, the description of the angeltype usually includes contact data such as a DECT number or an e-mail address that can be used. Alternatively, you can also ask one of the persons of the respective angeltype mentioned under &#34;Supporter&#34;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://angelguide.c3heaven.de/#_teams&#34;&gt;Teams&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Congress is organized from different teams, each with its own area of expertise.&lt;/p&gt; &lt;p&gt;All teams are self-organized and provide their own set of services to the event.&lt;/p&gt; &lt;p&gt;Teams spawn into existence by a need not fulfilled. They are seldom created by an authority.&lt;/p&gt; &lt;p&gt;Check out the &lt;a href=&#34;https://angelguide.c3heaven.de/#_teams&#34;&gt;different teams&lt;/a&gt; to see which one suits you best.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://jascha.wtf/angels-at-chaos-about-volunteering-and-fitting-in/&#34;&gt;Some poeple&lt;/a&gt; suggest not to try to fit into special roles at your first event. The roles will find you – not the other way around. Our com­mu­ni­ty is not about per­so­nal gro­wing but about con­tri­bu­ting to each other and gro­wing by doing this.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Perks&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Being an angel also comes with some perks. While we hope that participation is reward enough, here is a list of things that are exclusive to angels:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Community acknowledgement&lt;/li&gt; &lt;li&gt;Hanging out in Heaven and the angel hack center with its chill out area&lt;/li&gt; &lt;li&gt;Free coffee and (sparkling) water&lt;/li&gt; &lt;li&gt;Warm drinks or similar to make the cold night shifts more bearable&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Rewards&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you have contributed a certain amount of time, you may receive access to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Fantastic hot vegan and vegetarian meals&lt;/li&gt; &lt;li&gt;The famous limited™ angel T-shirt in Congress design&lt;/li&gt; &lt;li&gt;Maybe some other perks&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;feminism&#34;&gt;Feminism&lt;/h3&gt; &lt;h4 id=&#34;privileges&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/feminism/privileges/&#34;&gt;Privileges&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/feminism/privileges/#videos&#34;&gt;Add nice video on male privileges.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://twitter.com/almuariza/status/1772889815131807765?t=HH1W17VGbQ7K-_XmoCy_SQ&amp;amp;s=19&#34;&gt;La intuición femenina, gracias al lenguaje&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;free-knowledge&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/free_knowledge/&#34;&gt;Free Knowledge&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Update the way of seeding ill knowledge torrents.&lt;/p&gt; &lt;p&gt;A good way to contribute is by seeding the ill torrents. You can &lt;a href=&#34;https://annas-archive.org/torrents#generate_torrent_list&#34;&gt;generate a list of torrents that need seeding&lt;/a&gt; up to a limit in TB. If you follow this path, take care of IP leaking, they&#39;re&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;free-software&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/free_software/&#34;&gt;Free Software&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Recomendar el artículo El software libre también necesita jardineros.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://escritura.social/astrojuanlu/el-software-libre-tambien-necesita-jardineros&#34;&gt;El software libre también necesita jardineros&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;conference-organisation&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/conference_organisation/&#34;&gt;Conference organisation&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Software to manage the conference.&lt;/p&gt; &lt;p&gt;There are some open source software that can make your life easier when hosting a conference:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://frab.github.io/frab/&#34;&gt;Frab&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://pretalx.com/p/about/&#34;&gt;Pretalx&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://wafer.readthedocs.io/en/latest/&#34;&gt;Wafer&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;In addition to the management of talks from the call for papers till the event itself it can help the users visualise the talks schedule with &lt;a href=&#34;https://github.com/EventFahrplan/EventFahrplan?tab=readme-ov-file&#34;&gt;EventFahrplan&lt;/a&gt; which is what&#39;s used in the ChaosComputerClub congress.&lt;/p&gt; &lt;p&gt;If you also want to coordinate helpers and shifts take a look to &lt;a href=&#34;https://engelsystem.de/en&#34;&gt;Engelsystem&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;ludditest&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/luddites/&#34;&gt;Ludditest&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Nice comic about the luddites.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.technologyreview.com/2024/02/28/1088262/luddites-resisting-automated-future-technology/&#34;&gt;Comic about luddites&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;life-management&#34;&gt;Life Management&lt;/h2&gt; &lt;h3 id=&#34;time-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/time_management/&#34;&gt;Time management&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/time_management/#anticapitalist-approach-to-time-management&#34;&gt;Anticapitalist approach to time management.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Time management is being used to perpetrate the now hegemonic capitalist values. Its a pity because the underlying concepts are pretty useful and interesting but they are oriented towards improving productivity and being able to deal with an increasing amount of work. Basically they&#39;re always telling you to be a better cog. It doesn&#39;t matter how good you are, there is always room for improvement. I&#39;ve fallen on this trap for a long time (I&#39;m still getting my head out of the hole) and I&#39;m trying to amend things by applying the concepts on an anticapitalist mindset. The turning point was to read &lt;a href=&#34;https://en.wikipedia.org/wiki/Four_Thousand_Weeks:_Time_Management_for_Mortals&#34;&gt;Four thousand weeks: Time management for mortals by Oliver Burkeman&lt;/a&gt;, the article will have book extracts mixed with my way of thinking.&lt;/p&gt; &lt;p&gt;Some (or most) of what&#39;s written in this article may not apply if you&#39;re not a male, white, young, cis, hetero, European, university graduated, able-bodied, &#34;&#34;&#34;wealthy&#34;&#34;&#34; person. You need to be at a certain level of the social ladder to even start thinking in these terms. And depending on the number of oppressions you&#39;re suffering you&#39;ll have more or less room to maneuver. That margin is completely outside our control so by no means we should feel guilty of not being able to manage time. What follows are just guidelines to deal with this time anxiety imposed by the capitalist system with whatever air we have to breath.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Changing the language&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The easiest way to change the underlying meaning is to change the language. Some substitutions are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;work&lt;/code&gt; -&amp;gt; &lt;code&gt;focus&lt;/code&gt;: Nowadays we use &lt;code&gt;work&lt;/code&gt; everywhere even if it&#39;s not in the laboral environment. For example &lt;em&gt;I work very hard to achieve my goals&lt;/em&gt;. Working is the action of selling your time and energies in order to get the resources you need to live. It has an intrinsic meaning of sacrifice, doing something we don&#39;t want to do to get another thing in return. That&#39;s a tainted way of thinking about your personal time. I find &lt;code&gt;focus&lt;/code&gt; is a great substitute as it doesn&#39;t have all those connotations. There are similar substitutions based on the same argument, such as: &lt;code&gt;workspace&lt;/code&gt; -&amp;gt; &lt;code&gt;space of focus&lt;/code&gt;, &lt;code&gt;workflow&lt;/code&gt; -&amp;gt; &lt;code&gt;action flow&lt;/code&gt; or just &lt;code&gt;flow&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;&lt;code&gt;task&lt;/code&gt; -&amp;gt; &lt;code&gt;action&lt;/code&gt;: Similar to &lt;code&gt;work&lt;/code&gt; a &lt;code&gt;task&lt;/code&gt; is something you kind of feel obliged to do. It uses a negative mindset to set the perfect scenario to feel guilty when you fail to do them. But you&#39;re on your personal time, it should be fine not to do an action for whatever reason. &lt;code&gt;Action&lt;/code&gt; on the other side fosters a positive way of thinking, it suggests change, movement in a way that helps you move forward. There are also other derived words such as &lt;code&gt;task manager&lt;/code&gt; -&amp;gt; &lt;code&gt;action manager&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;&lt;code&gt;productivity&lt;/code&gt; -&amp;gt; &lt;code&gt;efficiency&lt;/code&gt;: &lt;code&gt;Productivy&lt;/code&gt; is the measurement of how fast or good you create products. And &lt;a href=&#34;https://dictionary.cambridge.org/dictionary/english/product&#34;&gt;products are&lt;/a&gt; something that is made to be sold. Again this introduces a monetary mindset on all aspects of our life. &lt;code&gt;Efficiency&lt;/code&gt; on the other side is the quality of achieving the largest amount of change using as little time, energy or effort as possible (&lt;a href=&#34;https://dictionary.cambridge.org/dictionary/english/efficiency&#34;&gt;Cambridge&lt;/a&gt; doesn&#39;t agree with me though :P. It may be because universities are also another important vector of spreading the capitalist values &lt;code&gt;:(&lt;/code&gt;). So using efficiency we&#39;re focusing more on improving the process itself, so it can be applied for example on how to optimize your enjoyment of doing nothing. Which is completely antagonistic to the concept of productivity.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Changing the mindset&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;There is a widespread feeling that we&#39;re always short on time. We&#39;re obsessed with our overfilled inboxes and lengthening todo lists, haunted by the guilty feeling that we ought to be getting more done, or different things done, or both. At the same time we&#39;re deluged with advice on living the fully optimized life to squeeze the most from your time. And it get&#39;s worse as you age because time seems to speed up as you get older, steadily accelerating until months begging to flash by in what feels like minutes.&lt;/p&gt; &lt;p&gt;The real problem isn&#39;t our limited time. It&#39;s that we&#39;ve unwittingly inherited, and feel pressured to live by a troublesome set of ideas about how to use our limited time, all of which are pretty much guaranteed to make things worse. What follows are a list of mindset changes from the traditional time management bibliography that can set the bases of a healthier Anticapitalist one.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Time is not a resource to spend&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Before timetables life rhythms emerged organically from the tasks they needed to do. You milked the cows when they needed milking and harvested the crops when it was harvest time. Anyone who would tried imposing an external schedule on any of that, for example, doing a month&#39;s milking in a single day to get it out of the way would rightly have been considered a lunatic.&lt;/p&gt; &lt;p&gt;There was no need to think of time as something abstract and separate from life. In those days before clocks, when you did need to explain how long something might take, your only option was to compare it with some other concrete activity. They were untroubled by any notion of time &#34;ticking away&#34; thus living a heightened awareness of the vividness of things, the feeling of timelesness. Also known as living in deep time, or being in the flow, when the boundary separating the self from the rest of reality grows blurry and time stands still.&lt;/p&gt; &lt;p&gt;There&#39;s one huge drawback in giving so little thought to the abstract idea of time, though, which is that it severely limits what you can accomplish. As soon as you want to coordinate the actions of more than a handful of people, you need a reliable, agreed-upon method of measuring time. This is why the first mechanical clocks came to be invented.&lt;/p&gt; &lt;p&gt;Making time standardized and visible in this fashion inevitably encourages people to think of it as an abstract thing with an independent existence, distinct from the specific activities on which one might spend it. &#34;time&#34; is what ticks away as the hands move around the clock face.&lt;/p&gt; &lt;p&gt;The next step was to start treating time as a resource, something to be bought and sold and used as efficiently as possible. This mindset shift serves as the precondition for all the uniquely modern ways in which we struggle with time today. Once time is a resource to be used, you start to feel pressure, whether from external forces or from yourself, to use it well, ant to berate yourself when you feel you&#39;ve wasted it. When you&#39;re faced with too many demands, it&#39;s easy to assume that the only answer must be to make &lt;em&gt;better use&lt;/em&gt; of time, by becoming more efficient, driving yourself harder, or working longer instead of asking whether the demands themselves might be unreasonable.&lt;/p&gt; &lt;p&gt;Soon your sense of self-worth gets completely bound up with how you&#39;re using time: it stops being merely the water in which you swim and turns into something you fell you need to dominate or control if you&#39;re to avoid feeling guilty, panicked or overwhelmed.&lt;/p&gt; &lt;p&gt;The fundamental problem is that this attitude towards time sets up a rigged game in which it&#39;s impossible ever to feel as though you&#39;re doing well enough. Instead of simply living our lives as they unfold in time it becomes difficult not to value each moment primarily according to its usefulness for some future goal, or for some future oasis of relaxation you hope to reach once your tasks are finally &#34;out of the way&#34;.&lt;/p&gt; &lt;p&gt;Ultimately it backfires. It wrenches us out of the present, leading to a life spent leaning into the future, worrying about whether things will work out, experiencing everything in terms of some later, hoped-for benefit, so that peace of mind never quite arrives. And it makes it all but impossible to experience &lt;em&gt;the flow&lt;/em&gt;, that sense of timeless time which depends on forgetting the abstract yardstick and plunging back into the vividness of reality instead.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;If you don&#39;t disavow capitalism an increase in efficiency will only make things worse&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;All this context makes us eager to believe the promises of time management frameworks (like &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/&#34;&gt;GTD&lt;/a&gt;) that if you improve your efficiency you&#39;ll get more time to enjoy your life. If you follow the right time management system, build the right habits, and apply sufficient self-discipline, you will win the struggle with time.&lt;/p&gt; &lt;p&gt;Reality then kicks in you never win the struggle and only feel more stressed and unhappy. You realize that all the time you&#39;ve saved is automatically filled up by more things to do in a never ending feedback loop. It&#39;s true that you get more done, and yet, paradoxically, you only feel busier, more anxious and somehow emptier as a result. Time feels like an unstoppable conveyor belt, bringing us new actions as fast as we can dispatch the old ones; and becoming more efficient just seems to cause the belt to speed up. Or else, eventually, to break down.&lt;/p&gt; &lt;p&gt;It also has another side-effect. As life accelerates, everyone grows more impatient. It&#39;s somehow vastly more aggravating to wait two minutes for the microwave than two hours for the oven, or ten seconds for a slow loading web page versus three days to receive the same information by mail.&lt;/p&gt; &lt;p&gt;Denying reality never works though. It may provide some immediate relief, because it allows you to go on thinking that at some point in the future you might, at last, feel totally in control. But it can&#39;t ever bring the sense that you&#39;re doing enough (that you &lt;em&gt;are&lt;/em&gt; enough) because it defines &lt;em&gt;enough&lt;/em&gt; as a kind of limitless control that no human can attain. Instead, the endless struggle leads to more anxiety and less fulfilling life. For example, the more you believe yo might succeed in &#34;fitting everything in&#34;, the more commitments you naturally take on, and the less you feel the need to ask whether each new commitment is truly worth a portion of your time, and so your days inevitably fill with more activities you don&#39;t especially value. The more you hurry, the more frustrating it is to encounter tasks that won&#39;t be hurried, the more compulsively you plan for the future, the more anxious you feel about any remaining uncertainties, of which there will always be plenty.&lt;/p&gt; &lt;p&gt;Time management used this way serves as a distraction to numb our minds:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;It may hide the sense of precariousness inherent to the capitalist world we live in. If you could meet every boss&#39;s demand, while launching various side projects on your own, maybe one day You&#39;d finally feel secure in your career and your finances.&lt;/li&gt; &lt;li&gt;Divert your energies from fully experiencing the reality in which you find yourself, holding at bay certain scary questions about what you&#39;re doing with your life, and whether major changes might not be needed. As long as you&#39;re always just on the cusp of mastering time, you can avoid the thought that what life is really demanding from you might involve surrendering the craving for mastery and diving into the unknown instead.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Embrace the finitude of time&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;We recoil from the notion that this is it. That &lt;em&gt;this life&lt;/em&gt;, with all its flaws and inescapable vulnerabilities, its extreme brevity, and our limited influence over how it unfolds, is the only one we&#39;ll get a shot at. Instead, we mentally fight against the way things are, so that we don&#39;t have to consciously participate in what it&#39;s like to feel claustrophobic, imprisoned, powerless, and constrained by reality.&lt;/p&gt; &lt;p&gt;Our troubled relationship with time arises largely from this same effort to avoid the painful constrains of reality. And most of our strategies for becoming more efficient make things worse, because they&#39;re really just ways of furthering the avoidance. After all, it&#39;s painful to confront how limited your time is, because it means that tough choices are inevitable and that you won&#39;t have time for all you once dreamed you might do. It&#39;s also painful to accept the limited control over the time you do get: maybe you simply lack the stamina or talent or other resources to perform well in all the roles you feel you should. And so, rather than face our limitations, we engage in avoidance strategies, in an effort to carry on feeling limitless. We push ourselves harder, chasing fantasies of the perfect work-life balance, or we implement time management systems that promise to make time for everything, so that tough choices won&#39;t be required. Or we procrastinate, which is another means of maintaining the feeling of omnipotent control over life, because you needn&#39;t risk the upsetting experience of failing at an intimidating project if you never even start it. We fill our minds with busyness and distraction to numb ourselves emotionally. Or we plan compulsively, because the alternative is to confront how little control over the future we really have.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Heal yourself from FOMO&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;In practical terms, a limit-embracing attitude to time means organizing your days with the understanding that you definitely won&#39;t have time for everything you want to do, or that other people want you to do, and so, at the very least, you can stop beating yourself up for failing. Since hard choices are unavoidable, what matters is learning to make them consciously, deciding what to focus on and what to neglect, rather than letting them get made by default, or deceiving yourself that, with enough hard work and the right time management tricks, you might not have to make them at all. It also means resisting the temptation to &#34;keep your options open&#34; in favour of deliberately making big, daunting, irreversible commitments, which you can&#39;t know in advance will turn out for the best, but which reliably prove more fulfilling in the end. And it means standing firm in the face of FOMO (fear of missing out) because you come to realize that missing out on something (indeed on almost everything) is basically guaranteed. Which isn&#39;t actually a problem anyway, it turns to, because &#34;missing out&#34; is what makes your choices meaningful in the first place. Every decision to use a portion of time on anything represents the sacrifice of all the other ways in which you could have spent that time, but didn&#39;t, and to willingly make that sacrifice is to take a stand, without reservation, on what matters most to you.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Embrace your control limits&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The more you try to manage your time with the goal of achieving a feeling of total control and freedom from the inevitable constrains of being human, the more stressful, empty, and frustrating life gets. But the more you confront the facts of finitude instead, and work with them, rather than against them, the more efficient, meaningful and joyful life becomes. Anxiety won&#39;t ever completely go away, we&#39;re even limited, apparently, in our capacity to embrace our limitations. But I&#39;m aware of no other time management technique that&#39;s half as effective as just facing the way things truly are.&lt;/p&gt; &lt;p&gt;Time pressure comes largely from forces outside our control: from a cutthroat economy; from the loss of the social safety networks that used to help ease the burdens of work and childcare; and from the sexist expectation that women must excel in their careers while assuming most of the responsibilities at home. None of that will be solved with time management. Fully facing the reality of it can only help though. So long as you continue to respond to impossible demands on your time by trying to persuade yourself that you might one day find some way to do the impossible, you&#39;re implicitly collaboration with those demands. Whereas once you deeply grasp that they are impossible, you&#39;ll stop believing the delusion that any of that is ever going to bring satisfaction and will be newly empowered to resist them, letting you focus instead on building the most meaningful life you can, in whatever situation you&#39;re in.&lt;/p&gt; &lt;p&gt;Seeing and accepting our limited powers over our time can prompt us to question the very idea that time is something you use in the first place. There is an alternative: the notion of letting time use you, approaching life not as an opportunity to implement your predetermined plans for success but as a matter of responding to the needs of your place and your moment in history.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Embrace the community constrains&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Moreover, most of us seek a specifically individualistic kind of mastery over time. Our culture&#39;s ideal is that you alone should control your schedule, doing whatever you prefer, whenever you want, because it&#39;s scary to confront the truth that almost everything worth doing depends on cooperating with others, and therefore on exposing yourself to the emotional uncertainties of relationships. In the end the more individual sovereignty you achieve over your time, the lonelier you get. The truth then is that freedom sometimes is to be found not in achieving greater sovereignty over your own schedule but in allowing yourself to be constrained by the rhythms of community. Participating in forms of social life where you don&#39;t get to decide exactly what you do or when you doi it. And it leads to the insight that meaningful efficiency often comes not from hurrying things up but from letting them take the time they take.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Live for today not tomorrow&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;It doesn&#39;t matter what you do, we all sense that there are always more important and fulfilling ways we could be spending our time, even if we can&#39;t say exactly what they are, yet we systematically spend our days doing other things instead. This feeling can take many forms: the desire to devote yourself to some larger cause, continuously demanding more from yourself, desiring to spend more time with your loved ones.&lt;/p&gt; &lt;p&gt;Our attempts to become more efficient may have the effect of pushing the genuinely important stuff even further over the horizon. Our days are spent trying to &#34;get through&#34; tasks, in order to get them &#34;out of the way&#34;, with the result that we live mentally in the future, waiting for when we&#39;ll finally get around to what really matters, and worrying in the meantime, that we don&#39;t measure up, that we might lack the drive or stamina to keep pace with the speed at which life now seems to move. We live in a constant spirit of joyless urgency.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/time_management/#time-is-not-a-resource-to-be-tamed&#34;&gt;Time is not a resource to be tamed.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You&#39;ll see everywhere the concept of &lt;code&gt;time management&lt;/code&gt;. I feel it&#39;s daring to suggest that you have the power to actually manage time. No you can&#39;t as much as you can&#39;t tame the sea. &lt;a href=&#34;#time-is-not-a-resource-to-be-spent&#34;&gt;Time is not a resource to be spent or be managed&lt;/a&gt;, the best we can do is to try to understand its flows and navigate it the best we can.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Keep on summing up Oliver Burkeman book.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Efficiency doesn&#39;t necessarily give you more time&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;We&#39;re eager to believe the promises of time management frameworks (like &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/&#34;&gt;GTD&lt;/a&gt;) that if you improve your efficiency you&#39;ll get more time to enjoy your life. If you follow the right time management system, build the right habits, and apply sufficient self-discipline, you will win the struggle with time.&lt;/p&gt; &lt;p&gt;Reality then kicks in you never win the struggle and only feel more stressed and unhappy. You realize that all the time you&#39;ve saved is automatically filled up by more things to do in a never ending feedback loop. Time feels like an unstoppable conveyor belt, bringing us new actions as fast as we can dispatch the old ones; and becoming more efficient just seems to cause the belt to speed up. Or else, eventually, to break down. It&#39;s true that you get more done, and yet, paradoxically, you only feel busier, more anxious and somehow emptier as a result.&lt;/p&gt; &lt;p&gt;It get&#39;s even worse because &lt;a href=&#34;https://lyz-code.github.io/blue-book/time_management/#importance-is-relative&#34;&gt;importance is relative&lt;/a&gt; and you may fall into &lt;a href=&#34;https://lyz-code.github.io/blue-book/time_management/#be-mindful-of-the-efficiency-trap&#34;&gt;efficiency traps&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Heal yourself from FOMO&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Another problem that FOMO brings us is that it leads us to lives where you &#34;truly lived&#34; only if you&#39;ve lived all the experiences you could live. This leads to a frustrating life as the world has infinite of them, so getting a handful of them under your belt brings you no closer to a sense of having feasted on life&#39;s possibilities. You lead yourself in another &lt;a href=&#34;#be-mindful-of-the-efficiency-trap&#34;&gt;efficiency trap&lt;/a&gt; where the more you experience the more additional wonderful experiences you sarta to feel you could have on top of all those you&#39;ve already had, with the result that the feeling of existential overwhelm gets worse. To fight this existential overwhelm you can resist the urge to consume more and more experiences and embrace the idea that you&#39;re going to miss most of them. You&#39;ll then be able to focus on fully enjoying the tiny slice of experiences you actually do have time for.&lt;/p&gt; &lt;p&gt;This FOMO fever is normal given the facts that we&#39;re more conscious of the limits of our time (after deterring the after life), the increase of choices that the world has brought us, and the internet amplifier.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;You do what you can do&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;It&#39;s usual to feel as though you absolutely must do more than you can do. We live overwhelmed in a constant anxiety of fearing, or knowing for certain, that the actions we want to carry out won&#39;t fit on our available time. It looks like this feeling arises on every step of the economic ladder (shown in the works of Daniel Markovits).&lt;/p&gt; &lt;p&gt;The thing is that the idea in itself doesn&#39;t make any sense. You can&#39;t do more than you can do even if you must. If you truly don&#39;t have time for everything you want to do, or feel you ought to do, or that others are badgering you to do, then, well, you don&#39;t have time, no matter how grave the consequences of failing to do it all might prove to be. So technically it&#39;s irrational to feel troubled by an overwhelming to-do list. You&#39;ll do what you can, you won&#39;t do what you can&#39;t, and the tyrannical inner voice insisting that you must do everything is simply mistaken. We rarely stop to consider things so rationally, though, because that would mean confronting the painful truth of our limitations. We would be forced to acknowledge that there are hard choices to be made: which balls to let drop, which people to disappoint, which ambitions to abandon, which roles to fail at... Instead, in an attempt to avoid these unpleasant truths, we deploy the strategy that dominates most conventional advice on how to deal with busyness: we tell ourselves we&#39;ll just have to find a way to do more. So to address our busyness we&#39;re making ourselves busier still.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Importance is relative&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The problem here is that you&#39;ll never be able to make time for everything that feels important. A similar mindset of the section &lt;a href=&#34;#efficiency-doesnt-give-you-more-time&#34;&gt;Efficiency doesn&#39;t give you more time&lt;/a&gt; can be applied. The reason isn&#39;t that you haven&#39;t yet discovered the right time management tricks, or applied sufficient effort, or that you&#39;re generally useless. It&#39;s that the underlying assumption is unwarranted: there&#39;s no reason to believe you&#39;ll make time for everything that matters simply by getting more done. For a start, what &#34;matters&#34; is subjective, so you&#39;ve no grounds for assuming that there will be time for everything that you, or anyone else deems important. But the other exasperating issue is that if you succeed in fitting more in, you&#39;ll find the goalposts start to shift: more things will begin to seem important, meaningful or obligatory. Acquire a reputation for doing your work at amazing speed, and you&#39;ll be given more of it. An example of this is gathered in Ruth Schwartz&#39;s book More work for mother, where it shows that when washing machines and vacuum cleaners appeared no time was saved at all, because society&#39;s standards of cleanliness rose to offset the benefits. What needs doing expands so as to fill the time available for its completion.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Be mindful of the efficiency trap&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Sometimes improving your efficiency may lead you to a worse scenario (&#34;efficiency trap&#34;) where you won&#39;t generally result in the feeling of having &#34;enough time&#34;, because, all else being equal, the demands will increase to offset any benefits. Far from getting things done, you&#39;ll be creating new things to do. A clear example of this is email management. Every time you reply to an email, there&#39;s a good chance of provoking a reply to that email, which itself may require another reply, and so on and so on. At the same time, you&#39;ll become known as someone who responds promptly to email, so more people will consider it worth their while to message you to begin with. So it&#39;s not simply that you never get though your email; it&#39;s that the process of &#34;getting through your email&#34; actually generates more email.&lt;/p&gt; &lt;p&gt;For most of us, most of the time, it isn&#39;t feasible to avoid the efficiency trap altogether, but you can stop believing you&#39;ll ever solve the challenge of busyness by cramming more in, because that just makes matters worse. And once you stop investing in the idea that you might one day achieve peace of mind that way, it becomes easier to find peace of mind in the present, in the midst of overwhelming demands, because you&#39;re no longer making your peace of mind dependent on dealing with all the demands. Once you stop believing that it might somehow be possible to avoid hard choices about time, it gets easier to make better ones.&lt;/p&gt; &lt;p&gt;If you also have the knowledge of the existence of the efficiency traps you may detect them and try to get the benefits without the penalties.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Do the important stuff&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The worst aspect of the trap is that it&#39;s also a matter of quality. The harder you struggle to fit everything in, the more of your time you&#39;ll find yourself spending on the least meaningful things. This is because the more firmly you believe it ought to be possible to find time for everything, the less pressure you&#39;ll feel to ask whether any given activity sis the best use of a portion of your time. Each time something new shows up, you&#39;ll be strongly biased in favor of accepting it, because you&#39;ll assume you needn&#39;t sacrifice any other tasks or opportunities in order to make space for it. Soon your life will be automatically filled with not just more things but with more trivial or tedious things.&lt;/p&gt; &lt;p&gt;The important stuff gets postponed because such tasks need your full focus, which means to wait until you have a good chunk of free time and fewer small-but-urgent tasks tugging at your attention. So you spend your energy into clearing the decks, cranking through the smaller stuff to get it out of the way, only to discover that doing so takes the whole day, that the decks are filled up again overnight and that the moment for doing the important stuff never arrives. One can waste years this way, systematically postponing precisely the things one cares the most.&lt;/p&gt; &lt;p&gt;What&#39;s needed in these situations is to resist the urges of being on top of everything and learn to live with the anxiety of feeling overwhelmed without automatically responding by trying to fit more in. Instead of clearing the decks, decline to do so, focusing instead on what&#39;s truly of greatest consequence while tolerating the discomfort of knowing that, as you do so, the decks will be filling up further, with emails and errands and other to-dos, many of which you may never get around to at all.&lt;/p&gt; &lt;p&gt;You&#39;ll sometimes still decide to drive yourself hard in an effort to squeeze more in, when circumstances absolutely require it. But that won&#39;t be your default mode, because you&#39;ll no longer be operating under the illusion of one day making time for everything.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Evaluate what you miss when you increase your efficiency&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Part of the benefits of efficiency is that you free yourself from tedious experiences, the side effect is that some times we&#39;re not conscious of being removing experiences that we valued. So even if everything runs more smoothly, smoothness is a dubious virtue, since it&#39;s often the unsmoothed textures of life that makes them livable, helping nurture the relationships that are crucial for mental and physical health, and for the resilience of our communities. For example if you buy online the groceries you miss the chance to regularly meet with your neighbours at your local grocery store.&lt;/p&gt; &lt;p&gt;Convenience makes things easy, but without regard to whether easiness is truly what&#39;s most valuable in any given context. When you render the process more convenient you drain it of its meaning. The effect of convenience isn&#39;t just that the given activity starts to feel less valuable, but that we stop engaging in certain valuable activities altogether, in favour of more convenient ones. Because you can stay home, order food online, and watch sitcoms on a streaming service, you find yourself doing so although you might be perfectly aware that you&#39;d have had a better time if you had met with your friends.&lt;/p&gt; &lt;p&gt;Meanwhile, those aspects of life that resist being made to run more smoothly start to seem repellent. When you can skip the line and buy concert tickets on your phone, waiting in line to vote in an election is irritating. As convenience colonizes everyday life, activities gradually sort themselves into two types: the kind that are now far more convenient, but that feel empty or out of sync with our true preferences; and the kind that now seem intensely annoying because of how inconvenient they remain. Resisting all this is difficult because the Capital is winning this discourse and you&#39;ll have more pressure from your environment to stay convenient.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;vdirsyncer&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vdirsyncer/&#34;&gt;vdirsyncer&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vdirsyncer/#database-is-locked&#34;&gt;Troubleshoot Database is locked.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;First try to kill all stray vdirsyncer processes, if that doesn&#39;t work check for more solutions in &lt;a href=&#34;https://github.com/pimutils/vdirsyncer/issues/720&#34;&gt;this issue&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vdirsyncer/#sync-to-a-read-only-ics&#34;&gt;Sync to a read-only ics.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;```ini [pair calendar_name] a = &#34;calendar_name_local&#34; b = &#34;calendar_name_remote&#34; collections = null conflict_resolution = [&#34;command&#34;, &#34;vimdiff&#34;] metadata = [&#34;displayname&#34;, &#34;color&#34;]&lt;/p&gt; &lt;p&gt;[storage calendar_name_local] type = &#34;filesystem&#34; path = &#34;~/.calendars/calendar_name&#34; fileext = &#34;.ics&#34;&lt;/p&gt; &lt;p&gt;[storage calendar_name_remote] type = &#34;http&#34; url = &#34;&lt;a href=&#34;https://example.org/calendar.ics&#34;&gt;https://example.org/calendar.ics&lt;/a&gt;&#34;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vdirsyncer/#automatically-sync-calendars&#34;&gt;Automatically sync calendars.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can use the script shown in the &lt;a href=&#34;#script-to-sync-emails-and-calendars-with-different-frequencies&#34;&gt;automatically sync emails&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;org-mode&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/&#34;&gt;Org Mode&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#start-working-on-a-task-dates&#34;&gt;Start working on a task dates.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;SCHEDULED&lt;/code&gt; defines when you are plan to start working on that task.&lt;/p&gt; &lt;p&gt;The headline is listed under the given date. In addition, a reminder that the scheduled date has passed is present in the compilation for today, until the entry is marked as done or &lt;a href=&#34;#how-to-deal-with-overdue-SCHEDULED-and-DEADLINE-tasks&#34;&gt;disabled&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Although is not a good idea (as it promotes the can pushing through the street), if you want to delay the display of this task in the agenda, use &lt;code&gt;SCHEDULED: &amp;lt;2004-12-25 Sat -2d&amp;gt;&lt;/code&gt; the task is still scheduled on the 25&lt;sup&gt;th&lt;/sup&gt; but will appear two days later. In case the task contains a repeater, the delay is considered to affect all occurrences; if you want the delay to only affect the first scheduled occurrence of the task, use &lt;code&gt;--2d&lt;/code&gt; instead.&lt;/p&gt; &lt;p&gt;Scheduling an item in Org mode should not be understood in the same way that we understand scheduling a meeting. Setting a date for a meeting is just &lt;a href=&#34;#appointments&#34;&gt;a simple appointment&lt;/a&gt;, you should mark this entry with a simple plain timestamp, to get this item shown on the date where it applies. This is a frequent misunderstanding by Org users. In Org mode, scheduling means setting a date when you want to start working on an action item.&lt;/p&gt; &lt;p&gt;You can set it with &lt;code&gt;&amp;lt;leader&amp;gt;s&lt;/code&gt; (Default: &lt;code&gt;&amp;lt;leader&amp;gt;ois&lt;/code&gt;)&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#deadlines&#34;&gt;Deadlines.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;DEADLINE&lt;/code&gt; are like &lt;a href=&#34;#appointments&#34;&gt;appointments&lt;/a&gt; in the sense that it defines when the task is supposed to be finished on. On the deadline date, the task is listed in the agenda. The difference with appointments is that you also see the task in your agenda if it is overdue and you can set a warning about the approaching deadline, starting &lt;code&gt;org_deadline_warning_days&lt;/code&gt; before the due date (14 by default). It&#39;s useful then to set &lt;code&gt;DEADLINE&lt;/code&gt; for those tasks that you don&#39;t want to miss that the deadline is over.&lt;/p&gt; &lt;p&gt;An example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;* TODO Do this
DEADLINE: &amp;lt;2023-02-24 Fri&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can set it with &lt;code&gt;&amp;lt;leader&amp;gt;d&lt;/code&gt; (Default: &lt;code&gt;&amp;lt;leader&amp;gt;oid&lt;/code&gt;).&lt;/p&gt; &lt;p&gt;If you need a different warning period for a special task, you can specify it. For example setting a warning period of 5 days &lt;code&gt;DEADLINE: &amp;lt;2004-02-29 Sun -5d&amp;gt;&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;If you&#39;re as me, you may want to remove the warning feature of &lt;code&gt;DEADLINES&lt;/code&gt; to be able to keep your agenda clean. Most of times you are able to finish the task in the day, and for those that you can&#39;t specify a &lt;code&gt;SCHEDULED&lt;/code&gt; date. To do so set the default number of days to &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;orgmode&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;org_deadline_warning_days&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Using too many tasks with a &lt;code&gt;DEADLINE&lt;/code&gt; will clutter your agenda. Use it only for the actions that you need to have a reminder, instead try to using &lt;a href=&#34;#appointments&#34;&gt;appointment&lt;/a&gt; dates instead. The problem of using appointments is that once the date is over you don&#39;t get a reminder in the agenda that it&#39;s overdue, if you need this, use &lt;code&gt;DEADLINE&lt;/code&gt; instead.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#how-to-deal-with-overdue-scheduled-and-deadline-tasks.&#34;&gt;How to deal with overdue SCHEDULED and DEADLINE tasks.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce org-rw.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/kenkeiras/org-rw&#34;&gt;&lt;code&gt;org-rw&lt;/code&gt;&lt;/a&gt; is a Python library to process your orgmode files.&lt;/p&gt; &lt;p&gt;Installation:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;org-rw
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Load an orgmode file:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;org_rw&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;load&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;your_file.org&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;r&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;doc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#using-lazyvim&#34;&gt;Install using lazyvim.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;s1&#34;&gt;&#39;nvim-orgmode/orgmode&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;err&#34;&gt;```&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lua&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;s1&#34;&gt;&#39;nvim-orgmode/orgmode&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;dependencies&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;nvim-treesitter/nvim-treesitter&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;lazy&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;event&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;VeryLazy&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;-- Load treesitter grammar for org&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;orgmode&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup_ts_grammar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;-- Setup treesitter&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;nvim-treesitter.configs&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;highlight&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;enable&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;additional_vim_regex_highlighting&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;org&#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;ensure_installed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;org&#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;-- Setup orgmode&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;orgmode&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;org_agenda_files&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;~/orgfiles/**/*&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;org_default_notes_file&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;~/orgfiles/refile.org&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
  &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
  &lt;span class=&#34;err&#34;&gt;```&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;dependencies&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;nvim-treesitter/nvim-treesitter&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;lazy&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;event&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;VeryLazy&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;-- Load treesitter grammar for org&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;orgmode&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup_ts_grammar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;-- Setup treesitter&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;nvim-treesitter.configs&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;highlight&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;enable&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;additional_vim_regex_highlighting&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;org&#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;ensure_installed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;org&#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;-- Setup orgmode&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;orgmode&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_agenda_files&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;~/orgfiles/**/*&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_default_notes_file&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;~/orgfiles/refile.org&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
  &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#troubleshoot-orgmode-with-dap&#34;&gt;Troubleshoot orgmode with dap.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use the next config and follow the steps of &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#create-an-issue-in-the-orgmode-repository&#34;&gt;Create an issue in the orgmode repository&lt;/a&gt;.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;[[set runtimepath=$VIMRUNTIME]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;[[set packpath=/tmp/nvim/site]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;package_root&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;/tmp/nvim/site/pack&#39;&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;install_path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;package_root&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;/packer/start/packer.nvim&#39;&lt;/span&gt;

&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;load_plugins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;packer&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;startup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;s1&#34;&gt;&#39;wbthomason/packer.nvim&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;nvim-treesitter/nvim-treesitter&#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;nvim-lua/plenary.nvim&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;nvim-orgmode/orgmode&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;nvim-telescope/telescope.nvim&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;lyz-code/telescope-orgmode.nvim&#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;jbyuki/one-small-step-for-vimkind&#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;mfussenegger/nvim-dap&#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;kristijanhusak/orgmode.nvim&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;branch&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;master&#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;package_root&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;package_root&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;compile_path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;install_path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;/plugin/packer_compiled.lua&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;_G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;load_config&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;orgmode&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup_ts_grammar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;nvim-treesitter.configs&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;highlight&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;enable&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;additional_vim_regex_highlighting&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;org&#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;

  &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;[[packadd nvim-treesitter]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;[[runtime plugin/nvim-treesitter.lua]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;[[TSUpdateSync org]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

  &lt;span class=&#34;c1&#34;&gt;-- Close packer after install&lt;/span&gt;
  &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;filetype&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;packer&#39;&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_win_close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;

  &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;orgmode&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;org_agenda_files&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;s1&#34;&gt;&#39;./*&#39;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

  &lt;span class=&#34;c1&#34;&gt;-- Reload current file if it&#39;s org file to reload tree-sitter&lt;/span&gt;
  &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;filetype&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;org&#39;&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;[[edit!]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isdirectory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;install_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;system&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;git&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;clone&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;https://github.com/wbthomason/packer.nvim&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;install_path&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;load_plugins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;packer&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;[[autocmd User PackerCompileDone ++once lua load_config()]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;else&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;load_plugins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;load_config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;telescope&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;defaults&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;preview&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
     &lt;span class=&#34;n&#34;&gt;enable&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;treesitter&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;vimgrep_arguments&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;ag&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;--nocolor&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;--noheading&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;--numbers&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;--column&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;--smart-case&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;--silent&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;--follow&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;--vimgrep&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;file_ignore_patterns&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;%.svg&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;%.spl&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;%.sug&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;%.bmp&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;%.gpg&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;%.pub&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;%.kbx&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;%.db&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;%.jpg&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;%.jpeg&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;%.gif&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;%.png&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;%.org_archive&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;%.flf&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;.cache&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;.git/&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;.thunderbird&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;.nas&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;mappings&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;-- Required so that folding works when opening a file in telescope&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;-- https://github.com/nvim-telescope/telescope.nvim/issues/559&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;CR&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[:stopinsert]]&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[call feedkeys(&#34;\&amp;lt;CR&amp;gt;&#34;)]]&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;C-j&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;move_selection_next&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;C-k&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;move_selection_previous&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;pickers&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;find_files&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;find_command&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;rg&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;--files&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;--hidden&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;--glob&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;!**/.git/*&#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;hidden&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;follow&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;extensions&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;fzf&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;fuzzy&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;                    &lt;span class=&#34;c1&#34;&gt;-- false will only do exact matching&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;override_generic_sorter&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;-- override the generic sorter&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;override_file_sorter&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;     &lt;span class=&#34;c1&#34;&gt;-- override the file sorter&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;case_mode&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;smart_case&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;        &lt;span class=&#34;c1&#34;&gt;-- or &#34;ignore_case&#34; or &#34;respect_case&#34;&lt;/span&gt;
                                       &lt;span class=&#34;c1&#34;&gt;-- the default case_mode is &#34;smart_case&#34;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;heading&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;treesitter&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;telescope&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;load_extension&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;orgmode&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keymap&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mapleader&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39; &#39;&lt;/span&gt;

&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;builtin&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;telescope.builtin&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;f&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;builtin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;find_files&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{})&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;F&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;:Telescope file_browser&amp;lt;cr&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_create_autocmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;FileType&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;pattern&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;org&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;group&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_create_augroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;orgmode_telescope_nvim&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;clear&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}),&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;callback&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;r&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;telescope&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;extensions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;orgmode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;refile_heading&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;g&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;telescope&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;extensions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;orgmode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;search_headings&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;orgmode&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup_ts_grammar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;org&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;orgmode&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;org_agenda_files&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;./*&#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;org_todo_keywords&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;TODO(t)&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;CHECK(c)&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;DOING(d)&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;RDEACTIVATED(r)&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;WAITING(w)&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;|&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;DONE(e)&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;REJECTED(j)&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;DUPLICATE(u)&#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;org_hide_leading_stars&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;org_deadline_warning_days&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;win_split_mode&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;horizontal&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;org_priority_highest&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;A&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;org_priority_default&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;C&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;org_priority_lowest&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;D&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;mappings&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;global&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_agenda&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;ga&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_capture&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;;c&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;org&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;c1&#34;&gt;-- Enter new items&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_meta_return&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;c-cr&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_insert_heading_respect_content&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;;&amp;lt;cr&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_insert_todo_heading&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;c-t&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_insert_todo_heading_respect_content&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;;t&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;

      &lt;span class=&#34;c1&#34;&gt;-- Heading promoting and demoting&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_toggle_heading&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;h&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_do_promote&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;h&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_do_demote&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;gt;h&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_promote_subtree&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;H&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_demote_subtree&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;gt;H&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;

      &lt;span class=&#34;c1&#34;&gt;-- Heading moving&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_move_subtree_up&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;leader&amp;gt;k&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_move_subtree_down&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;leader&amp;gt;j&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;

      &lt;span class=&#34;c1&#34;&gt;-- Heading navigation&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_next_visible_heading&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;c-j&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_previous_visible_heading&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;c-k&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_forward_heading_same_level&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;c-n&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_backward_heading_same_level&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;c-p&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;outline_up_heading&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;gp&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_open_at_point&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;gx&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;

      &lt;span class=&#34;c1&#34;&gt;-- State transition&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_todo&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;t&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;

      &lt;span class=&#34;c1&#34;&gt;-- Priority change&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_priority_up&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;-&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_priority_down&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;=&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;

      &lt;span class=&#34;c1&#34;&gt;-- Date management&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_deadline&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;d&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_schedule&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;s&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_time_stamp&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;;d&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_change_date&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;c-e&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;

      &lt;span class=&#34;c1&#34;&gt;-- Tag management&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_set_tags_command&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;T&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;

      &lt;span class=&#34;c1&#34;&gt;-- Archive management and refiling&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_archive_subtree&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;;a&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_toggle_archive_tag&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;;A&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;c1&#34;&gt;-- org_refile = &#39;&amp;lt;leader&amp;gt;r&#39;,  The refile is being handled below&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;agenda&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_agenda_later&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;c-n&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_agenda_earlier&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;c-p&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_agenda_switch_to&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;tab&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_agenda_goto&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;cr&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_agenda_priority_up&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;=&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_agenda_set_tags&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;T&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_agenda_deadline&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;d&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_agenda_schedule&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;s&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_agenda_archive&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;a&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;capture&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_capture_finalize&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;;w&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_capture_refile&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;;r&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;org_capture_kill&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;qqq&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;dap&#34;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;dap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;configurations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lua&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;nlua&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;request&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;attach&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Attach to running Neovim instance&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;dap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;adapters&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nlua&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;callback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;callback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;server&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;host&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;host&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;127.0.0.1&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;port&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;port&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;8086&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;b&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[:lua require&#34;dap&#34;.toggle_breakpoint()&amp;lt;CR&amp;gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;c&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[:lua require&#34;dap&#34;.continue()&amp;lt;CR&amp;gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[:lua require&#34;dap&#34;.step_over()&amp;lt;CR&amp;gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;m&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[:lua require&#34;dap&#34;.repl.open()&amp;lt;CR&amp;gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;N&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[:lua require&#34;dap&#34;.step_into()&amp;lt;CR&amp;gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;F12&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[:lua require&#34;dap.ui.widgets&#34;.hover()&amp;lt;CR&amp;gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;F5&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[:lua require&#34;osv&#34;.launch({port = 8086})&amp;lt;CR&amp;gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#hide-the-state-changes-in-the-folds&#34;&gt;Hide the state changes in the folds.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The folding of the recurring tasks iterations is also kind of broken. For the next example&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;** TODO Recurring task
   DEADLINE: &amp;lt;2024-02-08 Thu .+14d -0d&amp;gt;
   :PROPERTIES:
   :LAST_REPEAT: [2024-01-25 Thu 11:53]
   :END:
   - State &#34;DONE&#34; from &#34;TODO&#34; [2024-01-25 Thu 11:53]
   - State &#34;DONE&#34; from &#34;TODO&#34; [2024-01-10 Wed 23:24]
   - State &#34;DONE&#34; from &#34;TODO&#34; [2024-01-03 Wed 19:39]
   - State &#34;DONE&#34; from &#34;TODO&#34; [2023-12-11 Mon 21:30]
   - State &#34;DONE&#34; from &#34;TODO&#34; [2023-11-24 Fri 13:10]

   - [ ] Do X
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;When folded the State changes is not added to the Properties fold. It&#39;s shown something like:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;** TODO Recurring task
   DEADLINE: &amp;lt;2024-02-08 Thu .+14d -0d&amp;gt;
   :PROPERTIES:...
   - State &#34;DONE&#34; from &#34;TODO&#34; [2024-01-25 Thu 11:53]
   - State &#34;DONE&#34; from &#34;TODO&#34; [2024-01-10 Wed 23:24]
   - State &#34;DONE&#34; from &#34;TODO&#34; [2024-01-03 Wed 19:39]
   - State &#34;DONE&#34; from &#34;TODO&#34; [2023-12-11 Mon 21:30]
   - State &#34;DONE&#34; from &#34;TODO&#34; [2023-11-24 Fri 13:10]

   - [ ] Do X
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;I don&#39;t know if this is a bug or a feature, but when you have many iterations it&#39;s difficult to see the task description. So it would be awesome if they could be included into the properties fold or have their own fold.&lt;/p&gt; &lt;p&gt;I&#39;ve found though that if you set the &lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/issues/455&#34;&gt;&lt;code&gt;org_log_into_drawer = &#34;LOGBOOK&#34;&lt;/code&gt; in the config&lt;/a&gt; this is fixed.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#things-that-are-still-broken-or-not-developed&#34;&gt;Things that are still broken or not developed.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/issues/656&#34;&gt;The agenda does not get automatically refreshed&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/issues/655&#34;&gt;Uncheck checkboxes on recurring tasks once they are completed&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/issues/524&#34;&gt;Foldings when moving items around&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/issues/657&#34;&gt;Refiling from the agenda&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/issues/149&#34;&gt;Interacting with the logbook&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Rename Task to Action.&lt;/p&gt; &lt;p&gt;To remove the productivity capitalist load from the concept&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#how-to-deal-with-recurring-tasks-that-are-not-yet-ready-to-be-acted-upon&#34;&gt;How to deal with recurring tasks that are not yet ready to be acted upon.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;By default when you mark a recurrent task as &lt;code&gt;DONE&lt;/code&gt; it will transition the date (either appointment, &lt;code&gt;SCHEDULED&lt;/code&gt; or &lt;code&gt;DEADLINE&lt;/code&gt;) to the next date and change the state to &lt;code&gt;TODO&lt;/code&gt;. I found it confusing because for me &lt;code&gt;TODO&lt;/code&gt; actions are the ones that can be acted upon right now. That&#39;s why I&#39;m using the next states instead:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;INACTIVE&lt;/code&gt;: Recurrent task which date is not yet close so you should not take care of it.&lt;/li&gt; &lt;li&gt;&lt;code&gt;READY&lt;/code&gt;: Recurrent task which date &lt;a href=&#34;#how-to-deal-with-overdue-SCHEDULED-and-DEADLINE-tasks&#34;&gt;is overdue&lt;/a&gt;, we acknowledge the fact and mark the date as inactive (so that it doesn&#39;t clobber the agenda).&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The idea is that once an INACTIVE task reaches your agenda, either because the warning days of the &lt;code&gt;DEADLINE&lt;/code&gt; make it show up, or because it&#39;s the &lt;code&gt;SCHEDULED&lt;/code&gt; date you need to decide whether to change it to &lt;code&gt;TODO&lt;/code&gt; if it&#39;s to be acted upon immediately or to &lt;code&gt;READY&lt;/code&gt; and deactivate the date.&lt;/p&gt; &lt;p&gt;&lt;code&gt;INACTIVE&lt;/code&gt; then should be the default state transition for the recurring tasks once you mark it as &lt;code&gt;DONE&lt;/code&gt;. To do this, set in your config:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;org_todo_repeat_to_state&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;INACTIVE&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If a project gathers a list of recurrent subprojects or subactions it can have the next states:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;READY&lt;/code&gt;: If there is at least one subelement in state &lt;code&gt;READY&lt;/code&gt; and the rest are &lt;code&gt;INACTIVE&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;TODO&lt;/code&gt;: If there is at least one subelement in state &lt;code&gt;TODO&lt;/code&gt; and the rest may have &lt;code&gt;READY&lt;/code&gt; or &lt;code&gt;INACTIVE&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;INACTIVE&lt;/code&gt;: The project is not planned to be acted upon soon.&lt;/li&gt; &lt;li&gt;&lt;code&gt;WAITING&lt;/code&gt;: The project is planned to be acted upon but all its subelements are in &lt;code&gt;INACTIVE&lt;/code&gt; state.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#&amp;lt;c-i&amp;gt;-doesn&#39;t-go-up-in-the-jump-list&#34;&gt;Debug &lt;c-i&gt; doesn&#39;t go up in the jump list.&lt;/c-i&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It&#39;s because &lt;a href=&#34;https://github.com/neovim/neovim/issues/5916&#34;&gt;&lt;c-i&gt; is a synonym of &lt;tab&gt;&lt;/tab&gt;&lt;/c-i&gt;&lt;/a&gt;, and &lt;code&gt;org_cycle&lt;/code&gt; is &lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/blob/c0584ec5fbe472ad7e7556bc97746b09aa7b8221/lua/orgmode/config/defaults.lua#L146&#34;&gt;mapped by default as &lt;tab&gt;&lt;/tab&gt;&lt;/a&gt; If you&#39;re used to use &lt;code&gt;zc&lt;/code&gt; then you can disable the &lt;code&gt;org_cycle&lt;/code&gt; by setting the mapping &lt;code&gt;org_cycle = &#34;&amp;lt;nop&amp;gt;&#34;&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#python-libraries&#34;&gt;Python libraries.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://code.codigoparallevar.com/kenkeiras/org-rw&#34;&gt;org-rw&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;org-rw&lt;/code&gt; is a library designed to handle Org-mode files, offering the ability to modify data and save it back to the disk.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Pros&lt;/strong&gt;:&lt;/li&gt; &lt;li&gt;Allows modification of data and saving it back to the disk&lt;/li&gt; &lt;li&gt; &lt;p&gt;Includes tests to ensure functionality&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;:&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Documentation is lacking, making it harder to understand and use&lt;/li&gt; &lt;li&gt;The code structure is complex and difficult to read&lt;/li&gt; &lt;li&gt;Uses &lt;code&gt;unittest&lt;/code&gt; instead of &lt;code&gt;pytest&lt;/code&gt;, which some developers may prefer&lt;/li&gt; &lt;li&gt;Tests are not easy to read&lt;/li&gt; &lt;li&gt;Last commit was made five months ago, indicating potential inactivity&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/kenkeiras/org-rw&#34;&gt;Not very popular&lt;/a&gt;, with only one contributor, three stars, and no forks&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/karlicoss/orgparse&#34;&gt;orgparse&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;orgparse&lt;/code&gt; is a more popular library for parsing Org-mode files, with better community support and more contributors. However, it has significant limitations in terms of editing and saving changes.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Pros&lt;/strong&gt;:&lt;/li&gt; &lt;li&gt;More popular with 13 contributors, 43 forks, and 366 stars&lt;/li&gt; &lt;li&gt;Includes tests to ensure functionality&lt;/li&gt; &lt;li&gt; &lt;p&gt;Provides some documentation, available &lt;a href=&#34;https://orgparse.readthedocs.io/en/latest/&#34;&gt;here&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;:&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Documentation is not very comprehensive&lt;/li&gt; &lt;li&gt;Cannot write back to Org-mode files, limiting its usefulness for editing content&lt;ul&gt; &lt;li&gt;The author suggests using &lt;a href=&#34;https://github.com/karlicoss/inorganic&#34;&gt;inorganic&lt;/a&gt; to convert Org-mode entities to text, with examples available in doctests and the &lt;a href=&#34;https://github.com/karlicoss/orger&#34;&gt;orger&lt;/a&gt; library.&lt;/li&gt; &lt;li&gt;&lt;code&gt;inorganic&lt;/code&gt; is not popular, with one contributor, four forks, 24 stars, and no updates in five years&lt;/li&gt; &lt;li&gt;The library is only 200 lines of code&lt;/li&gt; &lt;li&gt;The &lt;code&gt;ast&lt;/code&gt; is geared towards single-pass document reading. While it is possible to modify the document object tree, writing back changes is more complicated and not a common use case for the author.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://tree-sitter.github.io/tree-sitter/&#34;&gt;Tree-sitter&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Tree-sitter is a powerful parser generator tool and incremental parsing library. It can build a concrete syntax tree for a source file and efficiently update the syntax tree as the source file is edited.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Pros&lt;/strong&gt;:&lt;/li&gt; &lt;li&gt;General enough to parse any programming language&lt;/li&gt; &lt;li&gt;Fast enough to parse on every keystroke in a text editor&lt;/li&gt; &lt;li&gt;Robust enough to provide useful results even in the presence of syntax errors&lt;/li&gt; &lt;li&gt;Dependency-free, with a runtime library written in pure C&lt;/li&gt; &lt;li&gt;Supports multiple languages through community-maintained parsers&lt;/li&gt; &lt;li&gt;Used by Neovim, indicating its reliability and effectiveness&lt;/li&gt; &lt;li&gt;Provides good documentation, available &lt;a href=&#34;https://tree-sitter.github.io/tree-sitter/using-parsers&#34;&gt;here&lt;/a&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;Python library, &lt;a href=&#34;https://github.com/tree-sitter/py-tree-sitter&#34;&gt;py-tree-sitter&lt;/a&gt;, simplifies the installation process&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;:&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Requires installation of Tree-sitter and the Org-mode language parser separately&lt;/li&gt; &lt;li&gt;The Python library does not handle the Org-mode language parser directly&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;To get a better grasp of Tree-sitter you can check their talks:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.thestrangeloop.com/2018/tree-sitter---a-new-parsing-system-for-programming-tools.html&#34;&gt;Strange Loop 2018&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=0CGzC_iss-8&#34;&gt;FOSDEM 2018&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=a1rC79DHpmY&#34;&gt;Github Universe 2017&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/novoid/lazyblorg/blob/master/lib/orgparser.py&#34;&gt;lazyblorg orgparser.py&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;lazyblorg orgparser.py&lt;/code&gt; is another tool for working with Org-mode files. However, I didn&#39;t look at it.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/time_management_abstraction_levels/#area&#34;&gt;Tweak area concept.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Model a group of projects that follow the same interest, roles or accountabilities. These are not things to finish but rather to use as criteria for analyzing, defining a specific aspect of your life and to prioritize its projects to reach a higher outcome. We&#39;ll use areas to maintain balance and sustainability on our responsibilities as we operate in the world. Areas&#39; titles don&#39;t contain verbs as they don&#39;t model actions. An example of areas can be &lt;em&gt;health&lt;/em&gt;, &lt;em&gt;travels&lt;/em&gt; or &lt;em&gt;economy&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;To filter the projects by area I set an area tag that propagates downstream. To find the area documents easily I add a section in the &lt;code&gt;index.org&lt;/code&gt; of the documentation repository. For example:&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/org_rw/#change-the-default-org-todo-keywords&#34;&gt;Change the default org-todo-keywords.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;orig&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&#39;&#39;* NEW_TODO_STATE First entry&lt;/span&gt;

&lt;span class=&#34;s1&#34;&gt;* NEW_DONE_STATE Second entry&#39;&#39;&#39;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;doc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;loads&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;orig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;environment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;s1&#34;&gt;&#39;org-todo-keywords&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;NEW_TODO_STATE | NEW_DONE_STATE&#34;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;orgzly&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgzly/&#34;&gt;Orgzly&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Migrate from Orgzly to Orgzly Revived.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;gancio&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/roadmap_adjustment/&#34;&gt;Gancio&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Change the concept of &lt;code&gt;Task&lt;/code&gt; for &lt;code&gt;Action&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;To remove the capitalist productive mindset from the concept&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/roadmap_adjustment/#action-cleaning&#34;&gt;Action cleaning.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Marking steps as done make help you get an idea of the evolution of the action. It can also be useful if you want to do some kind of reporting. On the other hand, having a long list of done steps (specially if you have many levels of step indentation may make the finding of the next actionable step difficult. It&#39;s a good idea then to often clean up all done items.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;For non recurring actions use the &lt;code&gt;LOGBOOK&lt;/code&gt; to move the done steps. for example: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;** DOING Do X
   :LOGBOOK:
   - [x] Done step 1
   - [-] Doing step 2
     - [x] Done substep 1
   :END:
   - [-] Doing step 2
     - [ ] substep 2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;This way the &lt;code&gt;LOGBOOK&lt;/code&gt; will be automatically folded so you won&#39;t see the progress but it&#39;s at hand in case you need it.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;For recurring actions:&lt;/li&gt; &lt;li&gt;Mark the steps as done&lt;/li&gt; &lt;li&gt;Archive the todo element.&lt;/li&gt; &lt;li&gt;Undo the archive.&lt;/li&gt; &lt;li&gt;Clean up the done items.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;This way you have a snapshot of the state of the action in your archive.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/roadmap_adjustment/#project-cleaning&#34;&gt;Project cleaning.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Similar to &lt;a href=&#34;#action-cleaning&#34;&gt;action cleaning&lt;/a&gt; we want to keep the state clean. If there are not that many actions under the project we can leave the done elements as &lt;code&gt;DONE&lt;/code&gt;, once they start to get clobbered up we can create a &lt;code&gt;Closed&lt;/code&gt; section.&lt;/p&gt; &lt;p&gt;For recurring projects:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Mark the actions as done&lt;/li&gt; &lt;li&gt;Archive the project element.&lt;/li&gt; &lt;li&gt;Undo the archive.&lt;/li&gt; &lt;li&gt;Clean up the done items.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/roadmap_adjustment/#trimester-review&#34;&gt;Trimester review.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The objectives of the trimester review are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Identify the areas to focus on for the trimester&lt;/li&gt; &lt;li&gt;Identify the tactics you want to use on those areas.&lt;/li&gt; &lt;li&gt;Review the previous trimester tactics&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The objectives are not:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;To review what you&#39;ve done or why you didn&#39;t get there.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;When to do the trimester reviews&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;As with &lt;a href=&#34;#personal-integrity-review&#34;&gt;personal integrity review&lt;/a&gt;, it&#39;s interesting to do analysis at representative moments. It gives it an emotional weight. You can for example use the solstices or my personal version of the solstices:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Spring analysis (1&lt;sup&gt;st&lt;/sup&gt; of March): For me the spring is the real start of the year, it&#39;s when life explodes after the stillness of the winter. The sun starts to set later enough so that you have light in the afternoons, the climate gets warmer thus inviting you to be more outside, the nature is blooming new leaves and flowers. It is then a moment to build new projects and set the current year on track.&lt;/li&gt; &lt;li&gt;Summer analysis (1&lt;sup&gt;st&lt;/sup&gt; of June): I hate heat, so summer is a moment of retreat. Everyone temporarily stop their lives, we go on holidays and all social projects slow their pace. Even the news have even less interesting things to report. It&#39;s so hot outside that some of us seek the cold refuge of home or remote holiday places. Days are long and people love to hang out till late, so usually you wake up later, thus having less time to actually do stuff. Even in the moments when you are alone the heat drains your energy to be productive. It is then a moment to relax and gather forces for the next trimester. It&#39;s also perfect to develop &lt;em&gt;easy&lt;/em&gt; and &lt;em&gt;chill&lt;/em&gt; personal projects that have been forgotten in a drawer. Lower your expectations and just flow with what your body asks you.&lt;/li&gt; &lt;li&gt;Autumn analysis (1&lt;sup&gt;st&lt;/sup&gt; of September): September it&#39;s another key moment for many people. We have it hardcoded in our life since we were children as it was the start of school. People feel energized after the summer holidays and are eager to get back to their lives and stopped projects. You&#39;re already 6 months into the year, so it&#39;s a good moment to review your year plan and decide how you want to invest your energy reserves.&lt;/li&gt; &lt;li&gt;Winter analysis (1&lt;sup&gt;st&lt;/sup&gt; of December): December is the cue that the year is coming to an end. The days grow shorter and colder, they basically invite you to enjoy a cup of tea under a blanket. It is then a good time to get into your cave and do an introspection analysis on the whole year and prepare the ground for the coming year. Some of the goals of this season are:&lt;/li&gt; &lt;li&gt;Think everything you need to guarantee a good, solid and powerful spring start.&lt;/li&gt; &lt;li&gt;Do the year review to adjust your principles.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The year is then divided in two sets of an expansion trimester and a retreat one. We can use this information to adjust our life plan accordingly. In the expansion trimester we could invest more energies in the planning, and in the retreat ones we can do more throughout reviews.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Listen to your desires&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The trimester review requires an analysis that doesn&#39;t fill in a day session. It requires slow thinking over some time. So I&#39;m creating a task 10 days before the actual review to start thinking about the next trimester. Whether it&#39;s ideas, plans, desires, objectives, values, or principles.&lt;/p&gt; &lt;p&gt;Is useful for that document to be available wherever you go, so that in any spare time you can pop it up and continue with the train of thought.&lt;/p&gt; &lt;p&gt;Doing the reflection without seeing your life path prevents you from being tainted by it, thus representing the real you of right now.&lt;/p&gt; &lt;p&gt;On the day to actually do the review, follow the steps of the &lt;a href=&#34;#month-prepare&#34;&gt;Month review prepare&lt;/a&gt; adjusting them to the trimester case.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Answer some meaningful guided questions&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To be done, until then you can read chapters 13, 14 and the epilogue of the book Four thousand weeks by Oliver Burkman.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Refactor your gathered thoughts&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you&#39;ve followed the prepare steps, you&#39;ve already been making up your mind on what do you want the next trimester to look like. Now it&#39;s the time to refine those thoughts.&lt;/p&gt; &lt;p&gt;In your roadmap document add a new section for the incoming trimester similar to:&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;* Roadmap
** 2024
*** Summer 2024
**** Essential intent
**** Trimester analysis
**** Trimester objectives
***** TODO Objective 1
****** TODO SubObjective 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; Go &lt;em&gt;one by one&lt;/em&gt; (don&#39;t peek!) of your gathered items and translate them in the next sections:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;Trimester analysis&lt;/code&gt;: A text with as many paragraphs as you need to order your thoughts&lt;/li&gt; &lt;li&gt;&lt;code&gt;Trimester objectives&lt;/code&gt;: These can be concrete emotional projects you want to carry through.&lt;/li&gt; &lt;li&gt;&lt;code&gt;Essential intent&lt;/code&gt;: This is the main headline of your trimester, probably you won&#39;t be able to define it until the last parts of the review process. It should be concrete and emotional too, it&#39;s going to be the idea that gives you strength on your weak moments and your guide to decide which projects to do and which not to.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Don&#39;t be too concerned on the format of the content of the objectives, this is the first draft, and we&#39;ll refine it through the planning.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gancio/#wordpress-plugin&#34;&gt;Wordpress plugin.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This plugin allows you to embed a list of events or a single event from your Gancio website using a shortcode. It also allows you to connects a Gancio instance to a your wordpress website to automatically push events published on WordPress: for this to work an event manager plugin is required, Event Organiser and The Events Calendar are supported. Adding another plugin it’s an easy task and you have a guide available in the repo that shows you how to do it.&lt;/p&gt; &lt;p&gt;The source code of the plugin is &lt;a href=&#34;https://framagit.org/les/gancio/-/tree/master/wp-plugin?ref_type=heads&#34;&gt;in the wp-plugin&lt;/a&gt; directory of the official repo&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;habit-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/&#34;&gt;Habit management&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce habit management.&lt;/p&gt; &lt;p&gt;A &lt;a href=&#34;https://en.wikipedia.org/wiki/Habit&#34;&gt;habit&lt;/a&gt; is a routine of behavior that is repeated regularly and tends to occur subconsciously.&lt;/p&gt; &lt;p&gt;A &lt;a href=&#34;https://psycnet.apa.org/doiLanding?doi=10.1037%2F0022-3514.83.6.1281&#34;&gt;2002 daily experience study&lt;/a&gt; found that approximately 43% of daily behaviors are performed out of habit. New behaviours can become automatic through the process of habit formation. Old habits are hard to break and new habits are hard to form because the behavioural patterns that humans repeat become imprinted in neural pathways, but it is possible to form new habits through repetition.&lt;/p&gt; &lt;p&gt;When behaviors are repeated in a consistent context, there is an incremental increase in the link between the context and the action. This increases the automaticity of the behavior in that context. Features of an automatic behavior are all or some of: efficiency, lack of awareness, unintentionality, and uncontrollability.&lt;/p&gt; &lt;p&gt;Mastering habit formation can be a powerful tool to change yourself. Usually with small changes you get massive outcomes in the long run. The downside is that it&#39;s not for the impatient people as it often appears to make no difference until you cross a critical threshold that unlocks a new level of performance.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/#why-are-habits-interesting&#34;&gt;Why are habits interesting.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Whenever you face a problem repeatedly, your brain begins to automate the process of solving it. Habits are a series of automatic resolutions that solve the problems and stresses you face regularly.&lt;/p&gt; &lt;p&gt;As habits are created, the level of activity in the brain decreases. You learn to lock in on the cues that predict success and tune out everything else. When a similar situation arises in the future, you know exactly what you look for. There is no longer a need to analyze every angle of a situation. Your brain skips the process of trial and error and creates a mental rule: if this, then that.&lt;/p&gt; &lt;p&gt;Habit formation is incredibly useful because the conscious mind is the bottleneck of the brain. It can only pay attention to one problem at a time. Habits reduce the cognitive load and free up mental capacity, so they can be carried on with your nonconscious mind and you can allocate your attention to other tasks.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/#identity-focused-changes&#34;&gt;Identity focused changes.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Changing our habits is challenging because we try to change the wrong thing in the wrong way.&lt;/p&gt; &lt;p&gt;There are three levels at which change can occur:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Outcomes: Changing your results. Goals fall under this category: publishing a book, run daily&lt;/li&gt; &lt;li&gt;Process: Changing your habits and systems: decluttering your desk for a better workflow, developing a meditation practice.&lt;/li&gt; &lt;li&gt;Identity: Changing your beliefs, assumptions and biases: your world view, your self-image, your judgments.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Many people begin the process of changing their habits by focusing on what they want to achieve. This leads to outcome-based habits. The alternative is to build identity-based habits. With this approach, we start by focusing on who we wish to become.&lt;/p&gt; &lt;p&gt;The first path of change is doomed because maintaining behaviours that are incongruent with the self is expensive and will not last. Even if they make rational sense. Thus it&#39;s hard to change your habits if you never change the underlying beliefs that led to your past behaviour. On the other hand it&#39;s easy to find motivation once a habit has changed your identity as you may be proud of it and will be willing to maintain all the habits and systems associated with it. For example: The goal is not to read a book, but to become a reader.&lt;/p&gt; &lt;p&gt;Focusing on outcomes may also bring the next problems:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Focusing on the results may lead you to temporal solutions. If you focus on the source of the issue at hand you may solve it with less effort and get you to a more stable one.&lt;/li&gt; &lt;li&gt;Goals create an &#34;either-or&#34; conflict: either you achieve your goal and are successful or you fail and you are disappointed. Thus you only get a positive reward if you fulfill a goal. If you instead focus on the process rather than the result, you will be satisfied anytime your system is running.&lt;/li&gt; &lt;li&gt;When your hard work is focused on a goal you may feel depleted once you meet it and that could make you loose the condition that made you meet the goal in the first place.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Research has shown that once a person believes in a particular aspect of their identity, they are more likely to act in alignment with that belief. This of course is a double-edged sword. Identity change can be a powerful force for self-improvement. When working against you, identity change can be a curse.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/#changing-your-identity&#34;&gt;Changing your identity.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Whatever your identity is right now, you only believe it because you have proof of it. The more evidence you have for a belief, the more strongly you will believe it.&lt;/p&gt; &lt;p&gt;Your habits and systems are how you embody your identity. When you make your bed each day, you embody the identity of an organized person. The more you repeat a behaviour, the more you reinforce the identity associated with that behaviour. To the point that your self-image begins to change. The effect of one-off experiences tends to fade away while the effect of habits gets reinforced with time, which means your habits contribute most of the evidence that shapes your identity.&lt;/p&gt; &lt;p&gt;Every action you take is a vote for the type of person you wish to become. This is one reason why meaningful change does not require radical change. Small habits can make a meaningful difference by providing evidence of a new identity.&lt;/p&gt; &lt;p&gt;Once you start the ball rolling things become easier as building habits is a feedback loop. Your habits shape your identity, and your identity shapes your habits.&lt;/p&gt; &lt;p&gt;The most practical way to change the identity is to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/#decide-the-type-of-person-you-want-to-be&#34;&gt;Decide the type of person you want to be&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Prove it to yourself with small wins&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Another advantage of focusing in what type of person you want to be is that maybe the outcome you wanted to focus on is not the wisest smallest step to achieve your identity change. Thinking on the identity you want to embrace can make you think outside the box.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/#decide-the-type-of-person-you-want-to-be&#34;&gt;Decide the type of person you want to be.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;One way to decide the person you want to be is to answer big questions like: what do you want to stand for? What are your principles and values? Who do you wish to become?&lt;/p&gt; &lt;p&gt;As we&#39;re more result oriented, another way is to work backwards from them to the person you want to be. Ask yourself: Who is the type of person that could get the outcome I want?&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/#how-to-change-a-habit&#34;&gt;How to change a habit.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The process of building a habit from a behaviour can be divided into four stages:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Reward&lt;/strong&gt; is the end goal.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Cue&lt;/strong&gt; is the trigger in your brain that initiate a behaviour. It&#39;s contains the information that predicts a reward.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Cravings&lt;/strong&gt; are the motivational force fueled by the desire of the reward. Without motivation we have no reason to act.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Response&lt;/strong&gt; is the thought or action you perform to obtain the reward. The response depends on the amount of motivation you have, how much friction is associated with the behaviour and your ability to actually do it.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;If a behaviour is insufficient in any of the four stages, it will not become a habit. Eliminate the cue and your habit will never start. Reduce the craving and you won&#39;t have enough motivation to act. Make the behaviour difficult and you won&#39;t be able to do it. And if the reward fails to satisfy your desire, then you&#39;ll have no reason to do it again in the future.&lt;/p&gt; &lt;p&gt;We chase rewards because they:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Deliver contentment.&lt;/li&gt; &lt;li&gt;Satisfy your craving.&lt;/li&gt; &lt;li&gt;Teach us which actions are worth remembering in the future.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;If a reward is met then it becomes associated with the cue, thus closing the habit feedback loop.&lt;/p&gt; &lt;p&gt;If we keep these stages in mind then:&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;To build good habits we need to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Cue: Make it obvious&lt;/li&gt; &lt;li&gt;Craving: Make it attractive&lt;/li&gt; &lt;li&gt;Response: Make it easy&lt;/li&gt; &lt;li&gt;Reward: Make it satisfying&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;To break bad habits we need to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Cue: Make it invisible&lt;/li&gt; &lt;li&gt;Craving: Make it unattractive&lt;/li&gt; &lt;li&gt;Response: Make it difficult&lt;/li&gt; &lt;li&gt;Reward: Make it unsatisfying&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/#select-which-habits-you-want-to-work-with&#34;&gt;Select which habits you want to work with.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Our responses to the cues are so deeply encoded that it may feel like the urge to act comes from nowhere. For this reason, we must begin the process of behavior change with awareness. Before we can effectively build new habits, we need to get a handle on our current ones. The author suggests to do a list of your daily habits and rate them positively, negatively or neutral under the judgement of whether it brings you closer to the desired person you want to be.&lt;/p&gt; &lt;p&gt;I find this approach expensive time-wise if you already have a huge list of habits to work with. As it&#39;s my case I&#39;ll skip this part. You can read it in more detail in the chapter &#34;4: The Man Who Didn&#39;t Look Right&#34;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/#working-with-the-habit-cues&#34;&gt;Working with the habit cues.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The first place to start the habit design is to understand and tweak the triggers that produce them. We&#39;ll do it by:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/#clearly-formulate-the-habit-you-want-to-change&#34;&gt;Clearly formulating the habits to change&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/#habit-stacking&#34;&gt;Stacking habits&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/#use-the-environment-to-tweak-your-cues&#34;&gt;Using the environment to tweak your cues&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/#clearly-formulate-the-habit-you-want-to-change&#34;&gt;Clearly formulate the habit you want to change.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The cues that can trigger an habit can come in a wide range of forms but the two most common are time and location. Being specific about what you want and how you will achieve it helps you say no to things that derail progress, distract your attention and pull you off course. And with enough repetition, you will get the urge to do the right thing at the right time, even if you can&#39;t say why. That&#39;s why it&#39;s interesting to formulate your habits as &#34;I will [behaviour] at [time] in [location]&#34;.&lt;/p&gt; &lt;p&gt;You want the cue to be highly specific and immediately actionable. If there is room for doubt the implementation will suffer. Continuously refine the habit definitions as you catch the exceptions that drift you off.&lt;/p&gt; &lt;p&gt;If you aren&#39;t sure of when to start your habit, try the first day of the week, month or year. People are more likely to take action at those times because hope is usually higher as you get the feeling of a fresh start.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/#habit-stacking&#34;&gt;Habit stacking.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Many behaviours are linked together where the action of the first is the cue that triggers the next one. You can use this connection to build new habits based on your established ones. This may be called habit stacking. The formulation in this case is &#34;After [current habit], I will [new habit]&#34;.&lt;/p&gt; &lt;p&gt;The key is to tie your desired behaviour into something you already do each day. Once you have mastered this basic structure, you can begin to create larger stacks by chaining small habits together. The catch is that the new habit should have the same frequency as the established one.&lt;/p&gt; &lt;p&gt;One way to find the right trigger for your habit stack is by brainstorming over:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The list of your current habits.&lt;/li&gt; &lt;li&gt;A new list of things that always happen to you with that frequency.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;With these two lists, you can begin searching for the best triggers for the stack.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/#use-the-environment-to-tweak-your-cues&#34;&gt;Use the environment to tweak your cues.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The cues that trigger a habit can start out very specific, but over time your habits become associated not with a single trigger but with the entire context surrounding the behaviour. This stacks over itself and your habits change depending on the room you are in and the cues in front of you. The context or the environment is then the invisible hand that shapes behaviours. They are not defined by the objects in the environment but by our relationship to them.&lt;/p&gt; &lt;p&gt;A new environment is a good foundation to make new habits, as you are free from the subtle triggers that nudge you toward your current habits. When you can&#39;t manage to get an entirely new environment, you can redefine or rearrange your current one.&lt;/p&gt; &lt;p&gt;When building good habits you can rearrange the environment to create obvious visual cues that draw your attention towards the desired habit. By sprinkling triggers throughout your surroundings, you increase the odds that you&#39;ll think about your habit throughout the day.&lt;/p&gt; &lt;p&gt;Once a habit has been encoded, the urge to act follows whenever the environmental cues reappear. This is why bad habits reinforce themselves. As you carry through the behaviour you spiral into a situation where the craving keeps growing and points you to keep on going with the same response. For example watching TV makes you feel sluggish, so you watch more television because you don&#39;t have the energy to do anything else.&lt;/p&gt; &lt;p&gt;Even if you manage to break a habit, you are unlikely to forget it&#39;s cues even if you don&#39;t do it for a while. That means that simply resisting temptation is an ineffective strategy. In the short run it may work. In the long run, as self-control is an exhausting task that consumes willpower, we become a product of the environment we live in. Trying to change a habit with self-control is doomed to fail as you may be able to resist temptation once or twice, but it&#39;s unlikely you can muster the willpower to override your desires every time. It&#39;s also very hard and frustrating to try to achieve change when you&#39;re under the mood influences of a bad habit.&lt;/p&gt; &lt;p&gt;A more reliable approach is to cut bad habits off at the source. Tweak the environment to make the cue virtually impossible to happen. That way you won&#39;t even have the chance to fall for the craving.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/#temptation-bundling&#34;&gt;Temptation bundling.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Dopamine is a neurotransmitter that can be used as the scientific measurement of craving. For years we assumed that it was all about pleasure, but now we know it plays a central role in many neurological processes, including motivation, learning and memory, punishment and aversion and voluntary movement.&lt;/p&gt; &lt;p&gt;Habits are a dopamine-driven feed back loop. It is released not only when you receive a reward but also when you anticipate it. This anticipation, and not the fulfillment of it, is what gets us to take action.&lt;/p&gt; &lt;p&gt;If we make a habit more attractive it will release more dopamine which will gives us more motivation to carry it through.&lt;/p&gt; &lt;p&gt;Temptation bundling works by pairing an action you want to do with an action you need to do. You&#39;re more likely to find a behaviour attractive if you get to do one of your favourite things at the same time. In the end you may even look forward to do the habit you need as it&#39;s related to the habit you want.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/#align-your-personal-identity-change-with-an-existent-shared-identity&#34;&gt;Align your personal identity change with an existent shared identity.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;We pick up habits from the people around us. As a general rule, the closer we are to someone, the more likely we are to imitate some of their habits. One of the most effective things you can do to build better habits is to join a culture where your desired behaviour is the normal one. This transforms your personal identity transformation into the building of a shared one. Shared identities have great benefits over single ones:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;They foster belonging. A powerful feeling that creates motivation.&lt;/li&gt; &lt;li&gt;They are more resilient: When one falters others will take their place so all together you&#39;ll guarantee the maintenance of the identity.&lt;/li&gt; &lt;li&gt;They create friendship and community&lt;/li&gt; &lt;li&gt;They expose you to an environment where more habits tied to that identity thrive.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Likewise, if you&#39;re trying to run from a bad habit cut your ties to communities that embrace that habit.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/#track-your-habit-management&#34;&gt;Track your habit management.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can have a &lt;code&gt;habits.org&lt;/code&gt; file where you prioritize, analyze, track them.&lt;/p&gt; &lt;p&gt;I&#39;m using the next headings:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;em&gt;Habits being implemented&lt;/em&gt;: It&#39;s subdivided in two:&lt;/li&gt; &lt;li&gt;Habits that need attention&lt;/li&gt; &lt;li&gt;Habits that don&#39;t need attention&lt;/li&gt; &lt;li&gt;&lt;em&gt;Unclassified habits&lt;/em&gt;: Useful when refiling habits from your inbox. This list will be analyzedwhen you do habit analysis.&lt;/li&gt; &lt;li&gt;&lt;em&gt;Backlog of habits&lt;/em&gt;: Unrefined and unordered list of habits&lt;/li&gt; &lt;li&gt;Implemented habits:&lt;/li&gt; &lt;li&gt;Rejected habits:&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Each habit is a &lt;code&gt;TODO&lt;/code&gt; item with the usual states: &lt;code&gt;TODO&lt;/code&gt;, &lt;code&gt;DOING&lt;/code&gt;, &lt;code&gt;DONE&lt;/code&gt;, &lt;code&gt;REJECTED&lt;/code&gt;. In it&#39;s body I keep a log of the evolution and the analysis of the habit.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/#habit-management-workflow&#34;&gt;Habit management workflow.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Each month I&#39;m trying to go through the list of habits to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Update the state of the habits: Some will be done, rejected or to register ideas about them.&lt;/li&gt; &lt;li&gt;Decide which ones need attention.&lt;/li&gt; &lt;li&gt;Do habit analysis on the ones that need attention.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;For each of the habits that need analysis, apply the learnings of the next sections:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/#working-with-the-habit-cues&#34;&gt;Working with the habit cues&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/#working-with-the-habit-cravings&#34;&gt;Working with the habit cravings &lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/#working-with-the-habit-responses&#34;&gt;Working with the habit responses &lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/#working-with-the-habit-rewards&#34;&gt;Working with the habit rewards&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;calendar-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/calendar_management/&#34;&gt;Calendar management&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/calendar_management/#calendar-event-notification-system&#34;&gt;Add calendar event notification system tool.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Set up a system that notifies you when the next calendar event is about to start to avoid spending mental load on it and to reduce the possibilities of missing the event.&lt;/p&gt; &lt;p&gt;I&#39;ve created a small tool that:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Tells me the number of &lt;a href=&#34;task_tools.md#pomodoro&#34;&gt;pomodoros&lt;/a&gt; that I have until the next event.&lt;/li&gt; &lt;li&gt;Once a pomodoro finishes it makes me focus on the amount left so that I can prepare for the event&lt;/li&gt; &lt;li&gt;Catches my attention when the event is starting.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;life-chores-management&#34;&gt;Life chores management&lt;/h3&gt; &lt;h4 id=&#34;himalaya&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/grocy_management/&#34;&gt;himalaya&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/grocy_management/#doing-the-inventory-review&#34;&gt;Doing the inventory review.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I haven&#39;t found a way to make the grocy inventory match the reality because for me it&#39;s hard to register when I consume a product. Even more if other people also use them. Therefore I use grocy only to know what to buy without thinking about it. For that use case the inventory needs to meet reality only before doing the groceries. I usually do a big shopping of non-perishable goods at the supermarket once each two or three months, and a weekly shopping of the rest.&lt;/p&gt; &lt;p&gt;Tracking the goods that are bought each week makes no sense as those are things that are clearly seen and are very variable depending on the season. Once I&#39;ve automated the ingestion and consumption of products it will, but so far it would mean investing more time than the benefit it gives.&lt;/p&gt; &lt;p&gt;This doesn&#39;t apply to the big shopping, as this one is done infrequently, so we need a better planning.&lt;/p&gt; &lt;p&gt;To do the inventory review I use a tablet and the &lt;a href=&#34;https://github.com/patzly/grocy-android&#34;&gt;android app&lt;/a&gt;.&lt;/p&gt; &lt;ul class=&#34;task-list&#34;&gt; &lt;li class=&#34;task-list-item&#34;&gt;&lt;label class=&#34;task-list-control&#34;&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;/&gt;&lt;span class=&#34;task-list-indicator&#34;&gt;&lt;/span&gt;&lt;/label&gt; Open the stock overview and iterate through the locations to:&lt;/li&gt; &lt;li class=&#34;task-list-item&#34;&gt;&lt;label class=&#34;task-list-control&#34;&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;/&gt;&lt;span class=&#34;task-list-indicator&#34;&gt;&lt;/span&gt;&lt;/label&gt; Make sure that the number of products match the reality&lt;ul class=&#34;task-list&#34;&gt; &lt;li class=&#34;task-list-item&#34;&gt;&lt;label class=&#34;task-list-control&#34;&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;/&gt;&lt;span class=&#34;task-list-indicator&#34;&gt;&lt;/span&gt;&lt;/label&gt; Iterate over the list of products checking the quantity&lt;/li&gt; &lt;li class=&#34;task-list-item&#34;&gt;&lt;label class=&#34;task-list-control&#34;&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;/&gt;&lt;span class=&#34;task-list-indicator&#34;&gt;&lt;/span&gt;&lt;/label&gt; Look at the location to see if there are missing products in the inventory&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li class=&#34;task-list-item&#34;&gt;&lt;label class=&#34;task-list-control&#34;&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;/&gt;&lt;span class=&#34;task-list-indicator&#34;&gt;&lt;/span&gt;&lt;/label&gt; Adjust the product properties (default location, minimum amount)&lt;/li&gt; &lt;li class=&#34;task-list-item&#34;&gt;&lt;label class=&#34;task-list-control&#34;&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;/&gt;&lt;span class=&#34;task-list-indicator&#34;&gt;&lt;/span&gt;&lt;/label&gt; Check the resulting shopping list and adjust the minimum values.&lt;/li&gt; &lt;li class=&#34;task-list-item&#34;&gt;&lt;label class=&#34;task-list-control&#34;&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;/&gt;&lt;span class=&#34;task-list-indicator&#34;&gt;&lt;/span&gt;&lt;/label&gt; Check the list of missing products to adjust the minimum values. I have a notepad in the fridge where I write the things I miss.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce route management.&lt;/p&gt; &lt;p&gt;To analyze which hiking routes are available in a zone I&#39;m following the next process&lt;/p&gt; &lt;ul class=&#34;task-list&#34;&gt; &lt;li class=&#34;task-list-item&#34;&gt;&lt;label class=&#34;task-list-control&#34;&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;/&gt;&lt;span class=&#34;task-list-indicator&#34;&gt;&lt;/span&gt;&lt;/label&gt; Check in my &lt;code&gt;trips&lt;/code&gt; orgmode directory to see if the zone has already been indexed.&lt;/li&gt; &lt;li class=&#34;task-list-item&#34;&gt;&lt;label class=&#34;task-list-control&#34;&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;/&gt;&lt;span class=&#34;task-list-indicator&#34;&gt;&lt;/span&gt;&lt;/label&gt; Do a first search of routes&lt;/li&gt; &lt;li class=&#34;task-list-item&#34;&gt;&lt;label class=&#34;task-list-control&#34;&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;/&gt;&lt;span class=&#34;task-list-indicator&#34;&gt;&lt;/span&gt;&lt;/label&gt; Identify which books or magazines describe the zone&lt;/li&gt; &lt;li class=&#34;task-list-item&#34;&gt;&lt;label class=&#34;task-list-control&#34;&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;/&gt;&lt;span class=&#34;task-list-indicator&#34;&gt;&lt;/span&gt;&lt;/label&gt; For each of the described routes in each of these books:&lt;ul class=&#34;task-list&#34;&gt; &lt;li class=&#34;task-list-item&#34;&gt;&lt;label class=&#34;task-list-control&#34;&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;/&gt;&lt;span class=&#34;task-list-indicator&#34;&gt;&lt;/span&gt;&lt;/label&gt; Create the &lt;code&gt;Routes&lt;/code&gt; section with tag &lt;code&gt;:route:&lt;/code&gt; if it doesn&#39;t exist&lt;/li&gt; &lt;li class=&#34;task-list-item&#34;&gt;&lt;label class=&#34;task-list-control&#34;&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;/&gt;&lt;span class=&#34;task-list-indicator&#34;&gt;&lt;/span&gt;&lt;/label&gt; Fill up the route form in a &lt;code&gt;TODO&lt;/code&gt; heading. Something similar to: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Reference: Book Page
Source: Where does it start
Distance: X km
Slope: X m
Type: [Lineal/Circular/Semi-lineal]
Difficulty:
Track: URL (only if you don&#39;t have to search for it)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt; &lt;li class=&#34;task-list-item&#34;&gt;&lt;label class=&#34;task-list-control&#34;&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;/&gt;&lt;span class=&#34;task-list-indicator&#34;&gt;&lt;/span&gt;&lt;/label&gt; Add tags of the people I&#39;d like to do it with&lt;/li&gt; &lt;li class=&#34;task-list-item&#34;&gt;&lt;label class=&#34;task-list-control&#34;&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;/&gt;&lt;span class=&#34;task-list-indicator&#34;&gt;&lt;/span&gt;&lt;/label&gt; Put a postit on the book/magazine if it&#39;s likely I&#39;m going to do it&lt;/li&gt; &lt;li class=&#34;task-list-item&#34;&gt;&lt;label class=&#34;task-list-control&#34;&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;/&gt;&lt;span class=&#34;task-list-indicator&#34;&gt;&lt;/span&gt;&lt;/label&gt; Open a web maps tab with the source of the route to calculate the time from the different lodgins&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li class=&#34;task-list-item&#34;&gt; &lt;p&gt;&lt;label class=&#34;task-list-control&#34;&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;/&gt;&lt;span class=&#34;task-list-indicator&#34;&gt;&lt;/span&gt;&lt;/label&gt; If there are not enough, repeat the process above for each of your online route reference blogs&lt;/p&gt; &lt;/li&gt; &lt;li class=&#34;task-list-item&#34;&gt; &lt;p&gt;&lt;label class=&#34;task-list-control&#34;&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;/&gt;&lt;span class=&#34;task-list-indicator&#34;&gt;&lt;/span&gt;&lt;/label&gt; Choose the routes to do&lt;/p&gt; &lt;/li&gt; &lt;li class=&#34;task-list-item&#34;&gt;&lt;label class=&#34;task-list-control&#34;&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;/&gt;&lt;span class=&#34;task-list-indicator&#34;&gt;&lt;/span&gt;&lt;/label&gt; Show the gathered routes to the people you want to go with&lt;/li&gt; &lt;li class=&#34;task-list-item&#34;&gt; &lt;p&gt;&lt;label class=&#34;task-list-control&#34;&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;/&gt;&lt;span class=&#34;task-list-indicator&#34;&gt;&lt;/span&gt;&lt;/label&gt; Select which ones you&#39;ll be more likely to do&lt;/p&gt; &lt;/li&gt; &lt;li class=&#34;task-list-item&#34;&gt; &lt;p&gt;&lt;label class=&#34;task-list-control&#34;&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;/&gt;&lt;span class=&#34;task-list-indicator&#34;&gt;&lt;/span&gt;&lt;/label&gt; For each of the chosen routes&lt;/p&gt; &lt;/li&gt; &lt;li class=&#34;task-list-item&#34;&gt;&lt;label class=&#34;task-list-control&#34;&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;/&gt;&lt;span class=&#34;task-list-indicator&#34;&gt;&lt;/span&gt;&lt;/label&gt; Search the track in wikiloc if it&#39;s missing&lt;/li&gt; &lt;li class=&#34;task-list-item&#34;&gt;&lt;label class=&#34;task-list-control&#34;&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;/&gt;&lt;span class=&#34;task-list-indicator&#34;&gt;&lt;/span&gt;&lt;/label&gt; Import the track in &lt;a href=&#34;https://lyz-code.github.io/blue-book/osmand/&#34;&gt;OsmAnd+&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add API and python library docs.&lt;/p&gt; &lt;p&gt;There is no active python library, although it existed &lt;a href=&#34;https://github.com/SebRut/pygrocy&#34;&gt;pygrocy&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://demo.grocy.info/api&#34;&gt;API Docs&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce himalaya.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/pimalaya/himalaya&#34;&gt;himalaya&lt;/a&gt; is a Rust CLI to manage emails.&lt;/p&gt; &lt;p&gt;Features:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Multi-accounting&lt;/li&gt; &lt;li&gt;Interactive configuration via &lt;strong&gt;wizard&lt;/strong&gt; (requires &lt;code&gt;wizard&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;Mailbox, envelope, message and flag management&lt;/li&gt; &lt;li&gt;Message composition based on &lt;code&gt;$EDITOR&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;strong&gt;IMAP&lt;/strong&gt; backend (requires &lt;code&gt;imap&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Maildir&lt;/strong&gt; backend (requires &lt;code&gt;maildir&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Notmuch&lt;/strong&gt; backend (requires &lt;code&gt;notmuch&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;&lt;strong&gt;SMTP&lt;/strong&gt; backend (requires &lt;code&gt;smtp&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Sendmail&lt;/strong&gt; backend (requires &lt;code&gt;sendmail&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;Global system &lt;strong&gt;keyring&lt;/strong&gt; for managing secrets (requires &lt;code&gt;keyring&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;&lt;strong&gt;OAuth 2.0&lt;/strong&gt; authorization (requires &lt;code&gt;oauth2&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;&lt;strong&gt;JSON&lt;/strong&gt; output via &lt;code&gt;--output json&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;strong&gt;PGP&lt;/strong&gt; encryption:&lt;/li&gt; &lt;li&gt;via shell commands (requires &lt;code&gt;pgp-commands&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;via &lt;a href=&#34;https://www.gnupg.org/&#34;&gt;GPG&lt;/a&gt; bindings (requires &lt;code&gt;pgp-gpg&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;via native implementation (requires &lt;code&gt;pgp-native&lt;/code&gt; feature)&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Cons:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Documentation is inexistent, you have to dive into the &lt;code&gt;--help&lt;/code&gt; to understand stuff.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/pimalaya/himalaya&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;The &lt;code&gt;v1.0.0&lt;/code&gt; is currently being tested on the &lt;code&gt;master&lt;/code&gt; branch, and is the prefered version to use. Previous versions (including GitHub beta releases and repositories published versions) are not recommended.&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Himalaya CLI &lt;code&gt;v1.0.0&lt;/code&gt; can be installed with a pre-built binary. Find the latest &lt;a href=&#34;https://github.com/pimalaya/himalaya/actions/workflows/pre-release.yml&#34;&gt;&lt;code&gt;pre-release&lt;/code&gt;&lt;/a&gt; GitHub workflow and look for the &lt;em&gt;Artifacts&lt;/em&gt; section. You should find a pre-built binary matching your OS.&lt;/p&gt; &lt;p&gt;Himalaya CLI &lt;code&gt;v1.0.0&lt;/code&gt; can also be installed with &lt;a href=&#34;https://doc.rust-lang.org/cargo/&#34;&gt;cargo&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cargo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://github.com/pimalaya/himalaya.git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--force&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;himalaya
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;strong&gt;&lt;a href=&#34;https://github.com/pimalaya/himalaya?tab=readme-ov-file#configuration&#34;&gt;Configuration&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Just run &lt;code&gt;himalaya&lt;/code&gt;, the wizard will help you to configure your default account.&lt;/p&gt; &lt;p&gt;You can also manually edit your own configuration, from scratch:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Copy the content of the documented &lt;a href=&#34;https://github.com/pimalaya/himalaya/blob/master/config.sample.toml&#34;&gt;&lt;code&gt;./config.sample.toml&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Paste it in a new file &lt;code&gt;~/.config/himalaya/config.toml&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Edit, then comment or uncomment the options you want&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;If using mbrsync&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;My generic configuration for an mbrsync account is:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[accounts.account_name]

email = &#34;lyz@example.org&#34;
display-name = &#34;lyz&#34;
envelope.list.table.unseen-char = &#34;u&#34;
envelope.list.table.replied-char = &#34;r&#34;
backend.type = &#34;maildir&#34;
backend.root-dir = &#34;/home/lyz/.local/share/mail/lyz-example&#34;
backend.maildirpp = false
message.send.backend.type = &#34;smtp&#34;
message.send.backend.host = &#34;example.org&#34;
message.send.backend.port = 587
message.send.backend.encryption = &#34;start-tls&#34;
message.send.backend.login = &#34;lyz&#34;
message.send.backend.auth.type = &#34;password&#34;
message.send.backend.auth.command = &#34;pass show mail/lyz.example&#34;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Once you&#39;ve set it then you need to &lt;a href=&#34;#cannot-find-maildir-matching-name-inbox&#34;&gt;fix the INBOX directory&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Then you can check if it works by running &lt;code&gt;himalaya envelopes list -a lyz-example&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Vim plugin installation&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Using lazy:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;pimalaya/himalaya-vim&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can then run &lt;code&gt;:Himalaya account_name&lt;/code&gt; and it will open himalaya in your editor.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Configure the account bindings&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To avoid typing &lt;code&gt;:Himalaya account_name&lt;/code&gt; each time you want to check the email you can set some bindings:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;pimalaya/himalaya-vim&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;leader&amp;gt;ma&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;cmd&amp;gt;Himalaya account_name&amp;lt;cr&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Open account_name@example.org&#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;leader&amp;gt;ml&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;cmd&amp;gt;Himalaya lyz&amp;lt;cr&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Open lyz@example.org&#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Setting the description is useful to see the configured accounts with which-key by typing &lt;code&gt;&amp;lt;leader&amp;gt;m&lt;/code&gt; and waiting.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Configure extra bindings&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The default plugin doesn&#39;t yet have all the bindings I&#39;d like so I&#39;ve added the next ones:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;In the list of emails view:&lt;/li&gt; &lt;li&gt;&lt;code&gt;dd&lt;/code&gt; in normal mode or &lt;code&gt;d&lt;/code&gt; in visual: Delete emails&lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;code&gt;q&lt;/code&gt;: exit the program&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;In the email view:&lt;/p&gt; &lt;/li&gt; &lt;li&gt;&lt;code&gt;d&lt;/code&gt;: Delete email&lt;/li&gt; &lt;li&gt;&lt;code&gt;q&lt;/code&gt;: Return to the list of emails view&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;If you want them too set the next config:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;pimalaya/himalaya-vim&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_create_augroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;HimalayaCustomBindings&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;clear&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_create_autocmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;FileType&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;group&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;HimalayaCustomBindings&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;pattern&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;himalaya-email-listing&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;callback&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
          &lt;span class=&#34;c1&#34;&gt;-- Bindings to delete emails&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;dd&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;plug&amp;gt;(himalaya-email-delete)&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;x&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;d&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;plug&amp;gt;(himalaya-email-delete)&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
          &lt;span class=&#34;c1&#34;&gt;-- Bind `q` to close the window&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;q&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;:bd&amp;lt;CR&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;

      &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_create_augroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;HimalayaEmailCustomBindings&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;clear&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_create_autocmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;FileType&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;group&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;HimalayaEmailCustomBindings&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;pattern&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;mail&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;callback&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
          &lt;span class=&#34;c1&#34;&gt;-- Bind `q` to close the window&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;q&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;:q&amp;lt;CR&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
          &lt;span class=&#34;c1&#34;&gt;-- Bind `d` to delete the email and close the window&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
            &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&#34;d&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;plug&amp;gt;(himalaya-email-delete):q&amp;lt;CR&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
          &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
    &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Configure email fetching from within vim&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/pimalaya/himalaya-vim/issues/13&#34;&gt;Fetching emails from within vim&lt;/a&gt; is not yet supported, so I&#39;m manually refreshing by account:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;pimalaya/himalaya-vim&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;c1&#34;&gt;-- Email refreshing bindings&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;leader&amp;gt;rj&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;:lua FetchEmails(&#34;lyz&#34;)&amp;lt;CR&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Fetch lyz@example.org&#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
      &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;FetchEmails&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;notify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Fetching emails for &#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;, please wait...&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;levels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INFO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;redraw&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jobstart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;mbsync &#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;on_exit&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exit_code&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exit_code&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
              &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;notify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Emails for &#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34; fetched successfully!&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;levels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INFO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;kr&#34;&gt;else&lt;/span&gt;
              &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;notify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed to fetch emails for &#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;. Check the logs.&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;levels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ERROR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
      &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
    &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You still need to open again &lt;code&gt;:Himalaya account_name&lt;/code&gt; as the plugin does not reload if there are new emails.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Show notifications when emails arrive&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can set up &lt;a href=&#34;https://lyz-code.github.io/blue-book/mirador/&#34;&gt;mirador&lt;/a&gt; to get those notifications.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Not there yet&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/pimalaya/himalaya-vim/issues/8&#34;&gt;With the vim plugin you can&#39;t switch accounts&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/pimalaya/himalaya-vim/issues/12&#34;&gt;Let the user delete emails without confirmation&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/pimalaya/himalaya-vim/issues/13&#34;&gt;Fetching emails from within vim&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Troubleshooting&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/pimalaya/himalaya/issues/490&#34;&gt;Cannot find maildir matching name INBOX&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;mbrsync&lt;/code&gt; uses &lt;code&gt;Inbox&lt;/code&gt; instead of the default &lt;code&gt;INBOX&lt;/code&gt; so it doesn&#39;t find it. In theory you can use &lt;code&gt;folder.alias.inbox = &#34;Inbox&#34;&lt;/code&gt; but it didn&#39;t work with me, so I finally ended up doing a symbolic link from &lt;code&gt;INBOX&lt;/code&gt; to &lt;code&gt;Inbox&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Cannot find maildir matching name Trash&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;That&#39;s because the &lt;code&gt;Trash&lt;/code&gt; directory does not follow the Maildir structure. I had to create the &lt;code&gt;cur&lt;/code&gt; &lt;code&gt;tmp&lt;/code&gt; and &lt;code&gt;new&lt;/code&gt; directories.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt; - &lt;a href=&#34;https://github.com/pimalaya/himalaya&#34;&gt;Source&lt;/a&gt; - &lt;a href=&#34;https://github.com/pimalaya/himalaya-vim&#34;&gt;Vim plugin source&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce mailbox.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://docs.python.org/3/library/mailbox.html&#34;&gt;&lt;code&gt;mailbox&lt;/code&gt;&lt;/a&gt; is a python library to work with MailDir and mbox local mailboxes.&lt;/p&gt; &lt;p&gt;It&#39;s part of the core python libraries, so you don&#39;t need to install anything.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The docs are not very pleasant to read, so I got most of the usage knowledge from these sources:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://pymotw.com/2/mailbox/&#34;&gt;pymowt docs&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://cr-net.be/posts/maildir_cleanup_with_python/&#34;&gt;Cleanup maildir directories&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://gist.github.com/tyndyll/6f6145f8b1e82d8b0ad8&#34;&gt;Parsing maildir directories&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;One thing to keep in mind is that an account can have many mailboxes (INBOX, Sent, ...), there is no &#34;root mailbox&#34; that contains all of the other&lt;/p&gt; &lt;p&gt;&lt;strong&gt;initialise a mailbox&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;mbox&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mailbox&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Maildir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;path/to/your/mailbox&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where the &lt;code&gt;path/to/your/mailbox&lt;/code&gt; is the directory that contains the &lt;code&gt;cur&lt;/code&gt;, &lt;code&gt;new&lt;/code&gt;, and &lt;code&gt;tmp&lt;/code&gt; directories.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Working with mailboxes&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;It&#39;s not very clear how to work with them, the Maildir mailbox contains the emails in iterators &lt;code&gt;[m for m in mbox]&lt;/code&gt;, it acts kind of a dictionary, you can get the keys of the emails with &lt;code&gt;[k for k in mbox.iterkeys]&lt;/code&gt;, and then you can &lt;code&gt;mbox[key]&lt;/code&gt; to get an email, you cannot modify those emails (flags, subdir, ...) directly in the &lt;code&gt;mbox&lt;/code&gt; object (for example &lt;code&gt;mbox[key].set_flags(&#39;P&#39;)&lt;/code&gt; doesn&#39;t work). You need to &lt;code&gt;mail = mbox.pop(key)&lt;/code&gt;, do the changes in the &lt;code&gt;mail&lt;/code&gt; object and then &lt;code&gt;mbox.add(mail)&lt;/code&gt; it again, with the downside that after you added it again, the &lt;code&gt;key&lt;/code&gt; has changed! But it&#39;s the return value of the &lt;code&gt;add&lt;/code&gt; method.&lt;/p&gt; &lt;p&gt;If the program gets interrupted between the &lt;code&gt;pop&lt;/code&gt; and the &lt;code&gt;add&lt;/code&gt; then you&#39;ll loose the email. The best way to work with it would be then:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;mail = mbox.get(key)&lt;/code&gt; the email&lt;/li&gt; &lt;li&gt;Do all the process you need to do with the email&lt;/li&gt; &lt;li&gt;&lt;code&gt;mbox.pop(key)&lt;/code&gt; and &lt;code&gt;key = mbox.add(mail)&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;In theory &lt;code&gt;mbox&lt;/code&gt; has an &lt;code&gt;update&lt;/code&gt; method that does this, but I don&#39;t understand it and it doesn&#39;t work as expected :S.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Moving emails around&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can&#39;t just move the files between directories like you&#39;d do with python as each directory contains it&#39;s own identifiers.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Moving a message between the maildir directories&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The &lt;code&gt;Message&lt;/code&gt; has a &lt;code&gt;set_subdir&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://pymotw.com/2/mailbox/#maildir-folders&#34;&gt;Creating folders&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Even though you can create folders with &lt;code&gt;mailbox&lt;/code&gt; it creates them in a way that mbsync doesn&#39;t understand it. It&#39;s easier to manually create the &lt;code&gt;cur&lt;/code&gt;, &lt;code&gt;tmp&lt;/code&gt;, and &lt;code&gt;new&lt;/code&gt; directories. I&#39;m using the next function:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mailbox_dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;cur&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exists&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dir&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;cur&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;tmp&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;new&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mailbox_dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mkdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Initialized mailbox: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mailbox&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;debug&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mailbox&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; already exists&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://docs.python.org/3/library/mailbox.html&#34;&gt;Reference Docs&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://pymotw.com/2/mailbox/&#34;&gt;Non official useful docs&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce maildir.&lt;/p&gt; &lt;p&gt;The &lt;a href=&#34;https://en.wikipedia.org/wiki/Maildir&#34;&gt;Maildir&lt;/a&gt; e-mail format is a common way of storing email messages on a file system, rather than in a database. Each message is assigned a file with a unique name, and each mail folder is a file system directory containing these files.&lt;/p&gt; &lt;p&gt;A Maildir directory (often named Maildir) usually has three subdirectories named &lt;code&gt;tmp&lt;/code&gt;, &lt;code&gt;new&lt;/code&gt;, and &lt;code&gt;cur&lt;/code&gt;.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The &lt;code&gt;tmp&lt;/code&gt; subdirectory temporarily stores e-mail messages that are in the process of being delivered. This subdirectory may also store other kinds of temporary files.&lt;/li&gt; &lt;li&gt;The &lt;code&gt;new&lt;/code&gt; subdirectory stores messages that have been delivered, but have not yet been seen by any mail application.&lt;/li&gt; &lt;li&gt;The &lt;code&gt;cur&lt;/code&gt; subdirectory stores messages that have already been seen by mail applications.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Maildir&#34;&gt;Wikipedia&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/mbsync/#my-emails-are-not-being-deleted-on-the-source-imap-server&#34;&gt;My emails are not being deleted on the source IMAP server.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;That&#39;s the default behavior of &lt;code&gt;mbsync&lt;/code&gt;, if you want it to actually delete the emails on the source you need to add:&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Expunge Both
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; Under your channel (close to &lt;code&gt;Sync All&lt;/code&gt;, &lt;code&gt;Create Both&lt;/code&gt;)&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/mbsync/#mbsync-error:-uid-is-beyond-highest-assigned-uid&#34;&gt;Mbsync error: UID is beyond highest assigned UID.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If during the sync you receive the following errors:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mbsync error: UID is 3 beyond highest assigned UID 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Go to the place where &lt;code&gt;mbsync&lt;/code&gt; is storing the emails and find the file that is giving the error, you need to find the files that contain &lt;code&gt;U=3&lt;/code&gt;, imagine that it&#39;s something like &lt;code&gt;1568901502.26338_1.hostname,U=3:2,S&lt;/code&gt;. You can strip off everything from the &lt;code&gt;,U=&lt;/code&gt; from that filename and resync and it should be fine, e.g.&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;1568901502.26338_1.hostname,U=3:2,S&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;1568901502.26338_1.hostname&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; feat(mirador): introduce mirador&lt;/p&gt; &lt;p&gt;DEPRECATED: as of 2024-11-15 the tool has many errors (&lt;a href=&#34;https://github.com/pimalaya/mirador/issues/4&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;https://github.com/pimalaya/mirador/issues/3&#34;&gt;2&lt;/a&gt;), few stars (4) and few commits (8). use &lt;a href=&#34;https://lyz-code.github.io/blue-book/watchdog_python/&#34;&gt;watchdog&lt;/a&gt; instead and build your own solution.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/pimalaya/mirador&#34;&gt;mirador&lt;/a&gt; is a CLI to watch mailbox changes made by the maintaner of &lt;a href=&#34;https://lyz-code.github.io/blue-book/himalaya/&#34;&gt;himalaya&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Features:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Watches and executes actions on mailbox changes&lt;/li&gt; &lt;li&gt;Interactive configuration via &lt;strong&gt;wizard&lt;/strong&gt; (requires &lt;code&gt;wizard&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;Supported events: &lt;strong&gt;on message added&lt;/strong&gt;.&lt;/li&gt; &lt;li&gt;Supported actions: &lt;strong&gt;send system notification&lt;/strong&gt;, &lt;strong&gt;execute shell command&lt;/strong&gt;.&lt;/li&gt; &lt;li&gt;Supports &lt;strong&gt;IMAP&lt;/strong&gt; mailboxes (requires &lt;code&gt;imap&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;Supports &lt;strong&gt;Maildir&lt;/strong&gt; folders (requires &lt;code&gt;maildir&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;Supports global system &lt;strong&gt;keyring&lt;/strong&gt; to manage secrets (requires &lt;code&gt;keyring&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;Supports &lt;strong&gt;OAuth 2.0&lt;/strong&gt; (requires &lt;code&gt;oauth2&lt;/code&gt; feature)&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;em&gt;Mirador CLI is written in &lt;a href=&#34;https://www.rust-lang.org/&#34;&gt;Rust&lt;/a&gt;, and relies on &lt;a href=&#34;https://doc.rust-lang.org/cargo/reference/features.html&#34;&gt;cargo features&lt;/a&gt; to enable or disable functionalities. Default features can be found in the &lt;code&gt;features&lt;/code&gt; section of the &lt;a href=&#34;https://github.com/pimalaya/mirador/blob/master/Cargo.toml#L18&#34;&gt;&lt;code&gt;Cargo.toml&lt;/code&gt;&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/pimalaya/mirador&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The &lt;code&gt;v1.0.0&lt;/code&gt; is currently being tested on the &lt;code&gt;master&lt;/code&gt; branch, and is the preferred version to use. Previous versions (including GitHub beta releases and repositories published versions) are not recommended.*&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Cargo (git)&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Mirador CLI &lt;code&gt;v1.0.0&lt;/code&gt; can also be installed with &lt;a href=&#34;https://doc.rust-lang.org/cargo/&#34;&gt;cargo&lt;/a&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cargo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--frozen&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--force&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://github.com/pimalaya/mirador.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Pre-built binary&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Mirador CLI &lt;code&gt;v1.0.0&lt;/code&gt; can be installed with a pre-built binary. Find the latest &lt;a href=&#34;https://github.com/pimalaya/mirador/actions/workflows/pre-release.yml&#34;&gt;&lt;code&gt;pre-release&lt;/code&gt;&lt;/a&gt; GitHub workflow and look for the &lt;em&gt;Artifacts&lt;/em&gt; section. You should find a pre-built binary matching your OS.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Configuration&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Just run &lt;code&gt;mirador&lt;/code&gt;, the wizard will help you to configure your default account.&lt;/p&gt; &lt;p&gt;You can also manually edit your own configuration, from scratch:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Copy the content of the documented &lt;a href=&#34;https://github.com/pimalaya/mirador/blob/master/config.sample.toml&#34;&gt;&lt;code&gt;./config.sample.toml&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Paste it in a new file &lt;code&gt;~/.config/mirador/config.toml&lt;/code&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;Edit, then comment or uncomment the options you want&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/pimalaya/mirador&#34;&gt;Source&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/himalaya/#configure-navigation-bindings&#34;&gt;Configure navigation bindings.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The default bindings conflict with my git bindings, and to make them similar to orgmode agenda I&#39;m changing the next and previous page:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;pimalaya/himalaya-vim&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;b&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;plug&amp;gt;(himalaya-folder-select-previous-page)&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Go to the previous email page&#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;f&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;plug&amp;gt;(himalaya-folder-select-next-page)&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Go to the next email page&#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/himalaya/#configure-the-account-bindings&#34;&gt;Configure the account bindings.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Tweak the bindings.&lt;/p&gt; &lt;p&gt;Move forward and backwards in the history of emails:&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;    &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_create_autocmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;FileType&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;group&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;HimalayaCustomBindings&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;pattern&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;himalaya-email-listing&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;callback&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;b&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;plug&amp;gt;(himalaya-folder-select-previous-page)&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;f&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;plug&amp;gt;(himalaya-folder-select-next-page)&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
      &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; Better bindings for the email list view:&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;          &lt;span class=&#34;c1&#34;&gt;-- Refresh emails&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;r&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;:lua FetchEmails()&amp;lt;CR&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
          &lt;span class=&#34;c1&#34;&gt;-- Email list view bindings&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;b&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;plug&amp;gt;(himalaya-folder-select-previous-page)&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;f&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;plug&amp;gt;(himalaya-folder-select-next-page)&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;R&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;plug&amp;gt;(himalaya-email-reply-all)&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;F&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;plug&amp;gt;(himalaya-email-forward)&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;m&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;plug&amp;gt;(himalaya-folder-select)&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;M&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;plug&amp;gt;(himalaya-email-move)&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; feat(himalaya#Searching emails): Searching emails&lt;/p&gt; &lt;p&gt;You can use the &lt;code&gt;g/&lt;/code&gt; binding from within nvim to search for emails. The query syntax supports filtering and sorting query.&lt;/p&gt; &lt;p&gt;I&#39;ve tried changing it to &lt;code&gt;/&lt;/code&gt; without success :&#39;(&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Filters&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;A filter query is composed of operators and conditions. There is 3 operators and 8 conditions:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;not &amp;lt;condition&amp;gt;&lt;/code&gt;: filter envelopes that do not match the condition&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;condition&amp;gt; and &amp;lt;condition&amp;gt;&lt;/code&gt;: filter envelopes that match both conditions&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;condition&amp;gt; or &amp;lt;condition&amp;gt;&lt;/code&gt;: filter envelopes that match one of the conditions&lt;/li&gt; &lt;li&gt;&lt;code&gt;date &amp;lt;yyyy-mm-dd&amp;gt;&lt;/code&gt;: filter envelopes that match the given date&lt;/li&gt; &lt;li&gt;&lt;code&gt;before &amp;lt;yyyy-mm-dd&amp;gt;&lt;/code&gt;: filter envelopes with date strictly before the given one&lt;/li&gt; &lt;li&gt;&lt;code&gt;after &amp;lt;yyyy-mm-dd&amp;gt;&lt;/code&gt;: filter envelopes with date stricly after the given one&lt;/li&gt; &lt;li&gt;&lt;code&gt;from &amp;lt;pattern&amp;gt;&lt;/code&gt;: filter envelopes with senders matching the given pattern&lt;/li&gt; &lt;li&gt;&lt;code&gt;to &amp;lt;pattern&amp;gt;&lt;/code&gt;: filter envelopes with recipients matching the given pattern&lt;/li&gt; &lt;li&gt;&lt;code&gt;subject &amp;lt;pattern&amp;gt;&lt;/code&gt;: filter envelopes with subject matching the given pattern&lt;/li&gt; &lt;li&gt;&lt;code&gt;body &amp;lt;pattern&amp;gt;&lt;/code&gt;: filter envelopes with text bodies matching the given pattern&lt;/li&gt; &lt;li&gt;&lt;code&gt;flag &amp;lt;flag&amp;gt;&lt;/code&gt;: filter envelopes matching the given flag&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Sorting&lt;/strong&gt; A sort query starts by &#34;order by&#34;, and is composed of kinds and orders. There is 4 kinds and 2 orders:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;date [order]&lt;/code&gt;: sort envelopes by date&lt;/li&gt; &lt;li&gt;&lt;code&gt;from [order]&lt;/code&gt;: sort envelopes by sender&lt;/li&gt; &lt;li&gt;&lt;code&gt;to [order]&lt;/code&gt;: sort envelopes by recipient&lt;/li&gt; &lt;li&gt;&lt;code&gt;subject [order]&lt;/code&gt;: sort envelopes by subject&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;kind&amp;gt; asc&lt;/code&gt;: sort envelopes by the given kind in ascending order&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;kind&amp;gt; desc&lt;/code&gt;: sort envelopes by the given kind in descending order&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;subject foo and body bar&lt;/code&gt;: filter envelopes containing &#34;foo&#34; in their subject and &#34;bar&#34; in their text bodies &lt;code&gt;order by date desc subject&lt;/code&gt;: sort envelopes by descending date (most recent first), then by ascending subject &lt;code&gt;subject foo and body bar order by date desc subject&lt;/code&gt;: combination of the 2 previous examples&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/himalaya/#not-there-yet&#34;&gt;List more detected issues.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/pimalaya/himalaya-vim/issues/14&#34;&gt;Replying an email doesn&#39;t mark it as replied&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/himalaya/#cannot-install&#34;&gt;Troubleshoot cannot install the program.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Sometimes &lt;a href=&#34;https://github.com/pimalaya/himalaya/issues/513&#34;&gt;the installation steps fail&lt;/a&gt; as it&#39;s still not in stable. A workaround is to download the binary created by the &lt;a href=&#34;https://github.com/pimalaya/himalaya/actions/workflows/pre-releases.yml&#34;&gt;pre-release CI&lt;/a&gt;. You can do it by:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Click on the latest job&lt;/li&gt; &lt;li&gt;Click on jobs&lt;/li&gt; &lt;li&gt;Click on the job of your architecture&lt;/li&gt; &lt;li&gt;Click on &#34;Upload release&#34;&lt;/li&gt; &lt;li&gt;Search for &#34;Artifact download URL&#34; and download the file&lt;/li&gt; &lt;li&gt;Unpack it and add it somewhere in your &lt;code&gt;$PATH&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;alot&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/beancount/&#34;&gt;alot&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/beancount/#comments&#34;&gt;Comments.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Any text on a line after the character &lt;code&gt;;&lt;/code&gt; is ignored, text like this:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;; I paid and left the taxi, forgot to take change, it was cold.
2015-01-01 * &#34;Taxi home from concert in Brooklyn&#34;
  Assets:Cash      -20 USD  ; inline comment
  Expenses:Taxi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce matrix_highlight.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/DanilaFe/matrix-highlight&#34;&gt;Matrix Highlight&lt;/a&gt; is a decentralized and federated way of annotating the web based on Matrix.&lt;/p&gt; &lt;p&gt;Think of it as an open source alternative to &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/hypothesis/&#34;&gt;hypothesis&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;It&#39;s similar to &lt;a href=&#34;https://github.com/opentower/populus-viewer&#34;&gt;Populus&lt;/a&gt; but for the web.&lt;/p&gt; &lt;p&gt;I want to try it and investigate further specially if you can:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Easily extract the annotations&lt;/li&gt; &lt;li&gt;Activate it by default everywhere&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/sql/sql/#get-the-schema-of-a-table&#34;&gt;Get the schema of a table.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://stackoverflow.com/questions/25639088/show-table-structure-and-list-of-tables-in-postgresql&#34;&gt;Postgres&lt;/a&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;\d+ table_name
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/sql/sql/#get-the-last-row-of-a-table-&#34;&gt;Get the last row of a table.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;Table&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ORDER&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ID&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;DESC&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;LIMIT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce beanSQL.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://beancount.github.io/docs/beancount_query_language.html#introduction&#34;&gt;bean-sql&lt;/a&gt; is a language to query &lt;a href=&#34;https://lyz-code.github.io/blue-book/beancount/&#34;&gt;&lt;code&gt;beancount&lt;/code&gt;&lt;/a&gt; data.&lt;/p&gt; &lt;p&gt;References: - &lt;a href=&#34;https://beancount.github.io/docs/beancount_query_language.html#introduction&#34;&gt;Docs&lt;/a&gt; - &lt;a href=&#34;https://aumayr.github.io/beancount-sql-queries/&#34;&gt;Examples&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bean_sql/#get-the-quarter-of-a-date&#34;&gt;Get the quarter of a date.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use the &lt;code&gt;quarter(date)&lt;/code&gt; selector in the &lt;code&gt;SELECT&lt;/code&gt; . For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;quarter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;date&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;as&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;quarter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;sum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;WHERE&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;~&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;^Expenses:&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;OR&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;~&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;^Income:&#39;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;GROUP&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;quarter&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;It will return the quarter in the format &lt;code&gt;YYYY-QX&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/beancount/#building-your-own-dashboards&#34;&gt;Building your own dashboards.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I was wondering whether to create &lt;a href=&#34;https://lyz-code.github.io/blue-book/fava_dashboards/&#34;&gt;fava dashboards&lt;/a&gt; or to create them directly in &lt;a href=&#34;https://lyz-code.github.io/blue-book/grafana/&#34;&gt;grafana&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Pros of fava dashboards: - They are integrated in fava so it would be easy to browse other beancount data. Although this could be done as well in another window if I used grafana. - There is no need to &lt;a href=&#34;https://groups.google.com/g/beancount/c/R3C9c-BPOGI&#34;&gt;create the beancount grafana data source logic&lt;/a&gt;. - It&#39;s already a working project, I would need just to tweak an existent example.&lt;/p&gt; &lt;p&gt;Cons: - I may need to learn echarts and write JavaScript to tweak some of the dashboards. - I wouldn&#39;t have all my dashboards in the same place. - It only solves part of the problem, I&#39;d still need to write the &lt;a href=&#34;https://lyz-code.github.io/blue-book/bean_sql/&#34;&gt;bean-sql queries&lt;/a&gt;. But using beanql is probably the best way to extract data from beancount anyway. - It involves more magic than using grafana. - grafana dashboards are prettier. - I wouldn&#39;t use the grafana knowledge. - I&#39;d learn a new tool only to use it here instead of taking the chance to improve my grafana skillset.&lt;/p&gt; &lt;p&gt;I&#39;m going to try with &lt;a href=&#34;https://lyz-code.github.io/blue-book/fava_dashboards/&#34;&gt;fava dashboards&lt;/a&gt; and see how it goes&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Deprecate in favour of himalaya.&lt;/p&gt; &lt;p&gt;DEPRECATED: Use &lt;a href=&#34;https://lyz-code.github.io/blue-book/himalaya/&#34;&gt;himalaya&lt;/a&gt; instead.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/email_automation/#automatically-sync-emails&#34;&gt;Automatically sync emails.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I have many emails, and I want to fetch them with different frequencies, in the background and be notified if anything goes wrong.&lt;/p&gt; &lt;p&gt;For that purpose I&#39;ve created a python script, a systemd service and some loki rules to monitor it.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Script to sync emails and calendars with different frequencies&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The script iterates over the configured accounts in &lt;code&gt;accounts_config&lt;/code&gt; and runs &lt;code&gt;mbsync&lt;/code&gt; for email accounts and &lt;code&gt;vdirsyncer&lt;/code&gt; for email accounts based on some cron expressions. It logs the output in &lt;code&gt;logfmt&lt;/code&gt; format so that it&#39;s easily handled by &lt;a href=&#34;https://lyz-code.github.io/blue-book/loki/&#34;&gt;loki&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To run it you&#39;ll first need to create a virtualenv, I use &lt;code&gt;mkvirtualenv account_syncer&lt;/code&gt; which creates a virtualenv in &lt;code&gt;~/.local/share/virtualenv/account_syncer&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Then install the dependencies:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;aiocron
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then place this script somewhere, for example (&lt;code&gt;~/.local/bin/account_syncer.py&lt;/code&gt;)&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;asyncio&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;logging&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;datetime&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;asyncio.subprocess&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;aiocron&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;accounts_config&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;emails&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;s2&#34;&gt;&#34;account_name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;lyz&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;s2&#34;&gt;&#34;cron_expressions&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;*/15 9-23 * * *&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;s2&#34;&gt;&#34;account_name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;work&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;s2&#34;&gt;&#34;cron_expressions&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;*/60 8-17 * * 1-5&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# Monday-Friday&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;s2&#34;&gt;&#34;account_name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;monitorization&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;s2&#34;&gt;&#34;cron_expressions&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;*/5 * * * *&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;calendars&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;s2&#34;&gt;&#34;account_name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;lyz&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;s2&#34;&gt;&#34;cron_expressions&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;*/15 9-23 * * *&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;s2&#34;&gt;&#34;account_name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;work&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;s2&#34;&gt;&#34;cron_expressions&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;*/60 8-17 * * 1-5&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# Monday-Friday&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;LogfmtFormatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Formatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Custom formatter to output logs in logfmt style.&#34;&#34;&#34;&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;record&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogRecord&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;log_message&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;level=&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;record&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;levelname&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lower&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; &#34;&lt;/span&gt;
            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;logger=&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;record&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; &#34;&lt;/span&gt;
            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;msg=&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;record&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#34;&#39;&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;log_message&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;setup_logging&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Logger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Configure logging to use logfmt format.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    Args:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        logging_name (str): The logger&#39;s name and identifier in the systemd journal.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    Returns:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        Logger: The configured logger.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    &#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;console_handler&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;StreamHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;logfmt_formatter&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;LogfmtFormatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;console_handler&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setFormatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logfmt_formatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getLogger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setLevel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INFO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;addHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;console_handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;log&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;setup_logging&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;account_syncer&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;run_mbsync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Run mbsync command asynchronously for email accounts.&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;    Args:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        account_name (str): The name of the email account to sync.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    &#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;command&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;mbsync &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Syncing emails for &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;...&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;process&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;create_subprocess_shell&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stdout&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PIPE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PIPE&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;stdout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;process&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;communicate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stdout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Output for &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stdout&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;decode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Error for &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;decode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;run_vdirsyncer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Run vdirsyncer command asynchronously for calendar accounts.&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;    Args:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        account_name (str): The name of the calendar account to sync.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    &#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;command&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;vdirsyncer sync &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Syncing calendar for &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;...&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;process&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;create_subprocess_shell&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stdout&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PIPE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PIPE&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;process&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;communicate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;command_log&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;decode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;strip&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;error&#34;&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;command_log&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;critical&#34;&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;command_log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Output for &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;command_log&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;elif&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;command_log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;splitlines&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Output for &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;command_log&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;should_i_sync_today&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cron_expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Check if the current time matches the cron expression day and hour constraints.&#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hour&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;day_of_week&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cron_expr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;split&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;now&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;*&#34;&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hour&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;elif&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hour&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;split&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;-&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hour&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hour&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;split&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;-&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])):&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;day_of_week&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;*&#34;&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;weekday&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;day_of_week&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;split&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;,&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Starting account syncer for emails and calendars&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;accounts_to_sync&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;emails&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[],&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;calendars&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]}&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;# Schedule email accounts&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;accounts_config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;emails&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;account_name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cron_expression&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;cron_expressions&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;should_i_sync_today&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cron_expression&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;accounts_to_sync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;emails&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;accounts_to_sync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;emails&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;aiocron&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crontab&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cron_expression&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run_mbsync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Scheduled mbsync for &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; with cron expression: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cron_expression&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;# Schedule calendar accounts&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;accounts_config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;calendars&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;account_name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cron_expression&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;cron_expressions&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;should_i_sync_today&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cron_expression&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;accounts_to_sync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;calendars&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;accounts_to_sync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;calendars&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;aiocron&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crontab&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cron_expression&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run_vdirsyncer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Scheduled vdirsyncer for &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; with cron expression: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cron_expression&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Running an initial fetch on today&#39;s accounts&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;accounts_to_sync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;emails&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;run_mbsync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;accounts_to_sync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;calendars&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;run_vdirsyncer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Finished loading accounts&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sleep&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;60&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;__main__&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;accounts_config&lt;/code&gt;: Holds your account configuration. Each account must contain an &lt;code&gt;account_name&lt;/code&gt; which should be the name of the &lt;code&gt;mbsync&lt;/code&gt; or &lt;code&gt;vdirsyncer&lt;/code&gt; profile, and &lt;code&gt;cron_expressions&lt;/code&gt; must be a list of cron valid expressions you want the email to be synced.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Create the systemd service&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;We&#39;re using a non-root systemd service. You can follow &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#create-a-systemd-service-for-a-non-root-user&#34;&gt;these instructions&lt;/a&gt; to configure this service:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[Unit]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Account Sync Service for emails and calendars&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;After&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;graphical-session.target&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Service]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;simple&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;ExecStart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/home/lyz/.local/share/virtualenvs/account_syncer/bin/python /home/lyz/.local/bin/&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;WorkingDirectory&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/home/lyz/.local/bin&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Restart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;on-failure&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;StandardOutput&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;journal&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;StandardError&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;journal&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;SyslogIdentifier&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;account_syncer&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Environment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;PATH=/home/lyz/.local/share/virtualenvs/account_syncer/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin&#34;&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Environment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;DISPLAY=:0&#34;&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Environment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus&#34;&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Install]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;WantedBy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;graphical-session.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Remember to tweak the service to match your current case and paths.&lt;/p&gt; &lt;p&gt;As we&#39;ll probably need to enter our &lt;code&gt;pass&lt;/code&gt; password we need the service to start once we&#39;ve logged into the graphical interface.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Monitor the automation&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;It&#39;s always nice to know if the system is working as expected without adding mental load. To do that I&#39;m creating the next &lt;a href=&#34;https://lyz-code.github.io/blue-book/loki/&#34;&gt;loki&lt;/a&gt; rules:&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;groups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;account_sync&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;AccountSyncIsNotRunningWarning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;(sum by(hostname) (count_over_time({job=&#34;systemd-journal&#34;, syslog_identifier=&#34;account_syncer&#34;}[15m])) or sum by(hostname) (count_over_time({hostname=&#34;my_computer&#34;} [15m])) * 0 ) == 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;sync&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;script&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;not&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;running&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;AccountSyncIsNotRunningError&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;(sum by(hostname) (count_over_time({job=&#34;systemd-journal&#34;, syslog_identifier=&#34;account_syncer&#34;}[3h])) or sum by(hostname) (count_over_time({hostname=&#34;my_computer&#34;} [3h])) * 0 ) == 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;error&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;sync&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;script&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;has&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;been&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;down&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;at&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;least&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;hours&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;AccountSyncError&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;count(rate({job=&#34;systemd-journal&#34;, syslog_identifier=&#34;account_syncer&#34;} |= `` | logfmt | level_extracted=`error` [5m])) &amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;There&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;are&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;errors&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;the&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;sync&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;at&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;EmailAccountIsOutOfSyncLyz&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;(sum by(hostname) (count_over_time({job=&#34;systemd-journal&#34;, syslog_identifier=&#34;account_syncer&#34;} | logfmt | msg=`Syncing emails for lyz...`[1h])) or sum by(hostname) (count_over_time({hostname=&#34;my_computer&#34;} [1h])) * 0 ) == 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;error&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;email&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;lyz&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;has&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;been&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;of&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;sync&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;1h&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;CalendarAccountIsOutOfSyncLyz&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;(sum by(hostname) (count_over_time({job=&#34;systemd-journal&#34;, syslog_identifier=&#34;account_syncer&#34;} | logfmt | msg=`Syncing calendar for lyz...`[3h])) or sum by(hostname) (count_over_time({hostname=&#34;my_computer&#34;} [3h])) * 0 ) == 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;error&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;calendar&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;lyz&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;has&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;been&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;of&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;sync&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;3h&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; Where: - You need to change &lt;code&gt;my_computer&lt;/code&gt; for the hostname of the device running the service - Tweak the OutOfSync alerts to match your account (change the &lt;code&gt;lyz&lt;/code&gt; part).&lt;/p&gt; &lt;p&gt;These rules will raise: - A warning if the sync has not shown any activity in the last 15 minutes. - An error if the sync has not shown any activity in the last 3 hours. - An error if there is an error in the logs of the automation.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;fava-dashboards&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/dino/&#34;&gt;Fava Dashboards&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Disable automatic OMEMO key acceptance.&lt;/p&gt; &lt;p&gt;Dino automatically accepts new OMEMO keys from your own other devices and your chat partners by default. This default behaviour leads to the fact that the admin of the XMPP server could inject own public OMEMO keys without user verification, which enables the owner of the associated private OMEMO keys to decrypt your OMEMO secured conversation without being easily noticed.&lt;/p&gt; &lt;p&gt;To prevent this, two actions are required, the second consists of several steps and must be taken for each new chat partner.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;First, the automatic acceptance of new keys from your own other devices must be deactivated. Configure this in the account settings of your own accounts.&lt;/li&gt; &lt;li&gt;Second, the automatic acceptance of new keys from your chat partners must be deactivated. Configure this in the contact details of every chat partner. Be aware that in the case of group chats, the entire communication can be decrypted unnoticed if even one partner does not actively deactivate automatic acceptance of new OMEMO keys.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Always confirm new keys from your chat partner before accepting them manually&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/dino/#dino-does-not-use-encryption-by-default&#34;&gt;Dino does not use encryption by default.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You have to initially enable encryption in the conversation window by clicking the lock-symbol and choose OMEMO. Future messages and file transfers to this contact will be encrypted with OMEMO automatically.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Every chat partner has to enable encryption separately.&lt;/li&gt; &lt;li&gt;If only one of two chat partner has activated OMEMO, only this part of the communication will be encrypted. The same applies with file transfers.&lt;/li&gt; &lt;li&gt;If you get a message &#34;This contact does not support OMEMO&#34; make sure that your chatpartner has accepted the request to add him to your contact list and you accepted vice versa&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/dino/#install-in-tails&#34;&gt;Install in Tails.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you have more detailed follow &lt;a href=&#34;https://t-hinrichs.net/DinoTails/DinoTails_recent.html&#34;&gt;this article&lt;/a&gt; at the same time as you read this one. That one is more outdated but more detailed.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Boot a clean Tails&lt;/li&gt; &lt;li&gt;Create and configure the Persistent Storage&lt;/li&gt; &lt;li&gt; &lt;p&gt;Restart Tails and open the Persistent Storage&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Configure the persistence of the directory: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-e&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;/home/amnesia/.local/share/dino source=dino&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tee&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/live/persistence/TailsData_unlocked/persistence.conf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/null
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Restart Tails&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Install the application: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dino-im
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Configure the &lt;code&gt;dino-im&lt;/code&gt; alias to use &lt;code&gt;torsocks&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;alias dino=&#34;torsocks dino-im &amp;amp;&amp;gt; /dev/null &amp;amp;&#34;&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/live/persistence/TailsData_unlocked/dotfiles/.bashrc
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;alias dino=&#34;torsocks dino-im &amp;amp;&amp;gt; /dev/null &amp;amp;&#34;&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;~/.bashrc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce Fava Dashboards.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;git+https://github.com/andreasgerstmayr/fava-dashboards.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Enable this plugin in Fava by adding the following lines to your ledger:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;2010-01-01 custom &#34;fava-extension&#34; &#34;fava_dashboards&#34;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then you&#39;ll need to &lt;a href=&#34;#configuration&#34;&gt;create a &lt;code&gt;dashboards.yaml&lt;/code&gt;&lt;/a&gt; file where your ledger lives.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/andreasgerstmayr/fava-dashboards/tree/main?tab=readme-ov-file#configuration&#34;&gt;Configuration&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The plugin looks by default for a &lt;code&gt;dashboards.yaml&lt;/code&gt; file in the directory of the Beancount ledger (e.g. if you run &lt;code&gt;fava personal.beancount&lt;/code&gt;, the &lt;code&gt;dashboards.yaml&lt;/code&gt; file should be in the same directory as &lt;code&gt;personal.beancount&lt;/code&gt;).&lt;/p&gt; &lt;p&gt;The configuration file can contain multiple dashboards, and a dashboard contains one or more panels. A panel has a relative width (e.g. &lt;code&gt;50%&lt;/code&gt; for 2 columns, or &lt;code&gt;33.3%&lt;/code&gt; for 3 column layouts) and a absolute height.&lt;/p&gt; &lt;p&gt;The &lt;code&gt;queries&lt;/code&gt; field contains one or multiple queries. The Beancount query must be stored in the &lt;code&gt;bql&lt;/code&gt; field of the respective query. It can contain Jinja template syntax to access the &lt;code&gt;panel&lt;/code&gt; and &lt;code&gt;ledger&lt;/code&gt; variables described below (example: use &lt;code&gt;{{ledger.ccy}}&lt;/code&gt; to access the first configured operating currency). The query results can be accessed via &lt;code&gt;panel.queries[i].result&lt;/code&gt;, where &lt;code&gt;i&lt;/code&gt; is the index of the query in the &lt;code&gt;queries&lt;/code&gt; field.&lt;/p&gt; &lt;p&gt;Note: Additionally to the Beancount query, Fava&#39;s filter bar further filters the available entries of the ledger.&lt;/p&gt; &lt;p&gt;Common code for utility functions can be defined in the dashboards configuration file, either inline in &lt;code&gt;utils.inline&lt;/code&gt; or in an external file defined in &lt;code&gt;utils.path&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;&lt;em&gt;Start your configuration&lt;/em&gt;&lt;/p&gt; &lt;p&gt;It&#39;s best to tweak the example than to start from scratch. Get the example by: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;mktemp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;clone&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://github.com/andreasgerstmayr/fava-dashboards
&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;fava-dashboards/example
fava&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;example.beancount
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Configuration reference&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;HTML, echarts and d3-sankey panels: The &lt;code&gt;script&lt;/code&gt; field must contain valid JavaScript code. It must return a valid configuration depending on the panel &lt;code&gt;type&lt;/code&gt;. The following variables and functions are available: * &lt;code&gt;ext&lt;/code&gt;: the Fava &lt;a href=&#34;https://github.com/beancount/fava/blob/main/frontend/src/extensions.ts&#34;&gt;&lt;code&gt;ExtensionContext&lt;/code&gt;&lt;/a&gt; * &lt;code&gt;ext.api.get(&#34;query&#34;, {bql: &#34;SELECT ...&#34;}&lt;/code&gt;: executes the specified BQL query * &lt;code&gt;panel&lt;/code&gt;: the current (augmented) panel definition. The results of the BQL queries can be accessed with &lt;code&gt;panel.queries[i].result&lt;/code&gt;. * &lt;code&gt;ledger.dateFirst&lt;/code&gt;: first date in the current date filter * &lt;code&gt;ledger.dateLast&lt;/code&gt;: last date in the current date filter * &lt;code&gt;ledger.operatingCurrencies&lt;/code&gt;: configured operating currencies of the ledger * &lt;code&gt;ledger.ccy&lt;/code&gt;: shortcut for the first configured operating currency of the ledger * &lt;code&gt;ledger.accounts&lt;/code&gt;: declared accounts of the ledger * &lt;code&gt;ledger.commodities&lt;/code&gt;: declared commodities of the ledger * &lt;code&gt;helpers.urlFor(url)&lt;/code&gt;: add current Fava filter parameters to url * &lt;code&gt;utils&lt;/code&gt;: the return value of the &lt;code&gt;utils&lt;/code&gt; code of the dashboard configuration&lt;/p&gt; &lt;p&gt;Jinja2 panels: The &lt;code&gt;template&lt;/code&gt; field must contain valid Jinja2 template code. The following variables are available: * &lt;code&gt;panel&lt;/code&gt;: see above * &lt;code&gt;ledger&lt;/code&gt;: see above * &lt;code&gt;favaledger&lt;/code&gt;: a reference to the &lt;code&gt;FavaLedger&lt;/code&gt; object&lt;/p&gt; &lt;p&gt;&lt;em&gt;Common Panel Properties&lt;/em&gt; * &lt;code&gt;title&lt;/code&gt;: title of the panel. Default: unset * &lt;code&gt;width&lt;/code&gt;: width of the panel. Default: 100% * &lt;code&gt;height&lt;/code&gt;: height of the panel. Default: 400px * &lt;code&gt;link&lt;/code&gt;: optional link target of the panel header. * &lt;code&gt;queries&lt;/code&gt;: a list of dicts with a &lt;code&gt;bql&lt;/code&gt; attribute. * &lt;code&gt;type&lt;/code&gt;: panel type. Must be one of &lt;code&gt;html&lt;/code&gt;, &lt;code&gt;echarts&lt;/code&gt;, &lt;code&gt;d3_sankey&lt;/code&gt; or &lt;code&gt;jinja2&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;HTML panel The &lt;code&gt;script&lt;/code&gt; code of HTML panels must return valid HTML. The HTML code will be rendered in the panel.&lt;/p&gt; &lt;p&gt;ECharts panel The &lt;code&gt;script&lt;/code&gt; code of &lt;a href=&#34;https://echarts.apache.org&#34;&gt;Apache ECharts&lt;/a&gt; panels must return valid &lt;a href=&#34;https://echarts.apache.org&#34;&gt;Apache ECharts&lt;/a&gt; chart options. Please take a look at the &lt;a href=&#34;https://echarts.apache.org/examples&#34;&gt;ECharts examples&lt;/a&gt; to get familiar with the available chart types and options.&lt;/p&gt; &lt;p&gt;d3-sankey panel The &lt;code&gt;script&lt;/code&gt; code of d3-sankey panels must return valid d3-sankey chart options. Please take a look at the example dashboard configuration &lt;a href=&#34;example/dashboards.yaml&#34;&gt;dashboards.yaml&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Jinja2 panel The &lt;code&gt;template&lt;/code&gt; field of Jinja2 panels must contain valid Jinja2 template code. The rendered template will be shown in the panel.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Debugging&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Add &lt;code&gt;console.log&lt;/code&gt; strings in the javascript code to debug it.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/andreasgerstmayr/fava-dashboards/tree/main?tab=readme-ov-file#configuration&#34;&gt;Code&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.andreasgerstmayr.at/2023/03/12/dashboards-with-beancount-and-fava.html&#34;&gt;Article&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/andreasgerstmayr/fava-portfolio-returns&#34;&gt;Fava Portfolio returns&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/andreasgerstmayr/fava-portfolio-returns&#34;&gt;Fava investor&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/fava_dashboards/#dashboard-prototypes&#34;&gt;Dashboard prototypes.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Vertical bars with one serie using year&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Net Year Profit 💰&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;50%&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;link&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/beancount/income_statement/&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;queries&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;bql&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;SELECT year, sum(position) AS value&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;WHERE&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;account ~ &#39;^Expenses:&#39; OR&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;account ~ &#39;^Income:&#39;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;GROUP BY year&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;link&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/beancount/balance_sheet/?time={time}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;echarts&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;script&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;const currencyFormatter = utils.currencyFormatter(ledger.ccy);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;const years = utils.iterateYears(ledger.dateFirst, ledger.dateLast)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;const amounts = {};&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;// the beancount query only returns periods where there was at least one matching transaction, therefore we group by period&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;for (let row of panel.queries[0].result) {&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;amounts[`${row.year}`] = -row.value[ledger.ccy];&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;return {&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;tooltip: {&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;trigger: &#34;axis&#34;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;valueFormatter: currencyFormatter,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;xAxis: {&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;data: years,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;yAxis: {&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;axisLabel: {&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;formatter: currencyFormatter,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;series: [&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;type: &#34;bar&#34;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;data: years.map((year) =&amp;gt; amounts[year]),&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;color: utils.green,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;],&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Vertical bars using one serie using quarters&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Net Quarter Profit 💰&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;50%&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;link&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/beancount/income_statement/&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;queries&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;bql&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;SELECT quarter(date) as quarter, sum(position) AS value&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;WHERE&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;account ~ &#39;^Expenses:&#39; OR&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;account ~ &#39;^Income:&#39;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;GROUP BY quarter&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;link&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/beancount/balance_sheet/?time={time}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;echarts&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;script&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;const currencyFormatter = utils.currencyFormatter(ledger.ccy);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;const quarters = utils.iterateQuarters(ledger.dateFirst, ledger.dateLast).map((q) =&amp;gt; `${q.year}-${q.quarter}`);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;const amounts = {};&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;// the beancount query only returns periods where there was at least one matching transaction, therefore we group by period&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;for (let row of panel.queries[0].result) {&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;amounts[`${row.quarter}`] = -row.value[ledger.ccy];&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;return {&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;tooltip: {&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;trigger: &#34;axis&#34;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;valueFormatter: currencyFormatter,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;xAxis: {&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;data: quarters,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;yAxis: {&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;axisLabel: {&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;formatter: currencyFormatter,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;series: [&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;type: &#34;bar&#34;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;data: quarters.map((quarter) =&amp;gt; amounts[quarter]),&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;],&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Vertical bars showing the evolution of one query over the months&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Net Year Profit Distribution 💰&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;50%&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;link&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/beancount/income_statement/&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;queries&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;bql&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;SELECT year, month, sum(position) AS value&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;WHERE&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;account ~ &#39;^Expenses:&#39; OR&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;account ~ &#39;^Income:&#39;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;GROUP BY year, month&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;link&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/beancount/balance_sheet/?time={time}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;echarts&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;script&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;const currencyFormatter = utils.currencyFormatter(ledger.ccy);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;const years = utils.iterateYears(ledger.dateFirst, ledger.dateLast);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;const amounts = {};&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;for (let row of panel.queries[0].result) {&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;if (!amounts[row.year]) {&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;amounts[row.year] = {};&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;amounts[row.year][row.month] = -row.value[ledger.ccy];&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;return {&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;tooltip: {&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;valueFormatter: currencyFormatter,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;legend: {&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;top: &#34;bottom&#34;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;xAxis: {&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;data: [&#39;0&#39;,&#39;1&#39;,&#39;2&#39;,&#39;3&#39;,&#39;4&#39;,&#39;5&#39;,&#39;6&#39;,&#39;7&#39;,&#39;8&#39;,&#39;9&#39;,&#39;10&#39;,&#39;11&#39;,&#39;12&#39;],&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;yAxis: {&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;axisLabel: {&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;formatter: currencyFormatter,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;series: years.map((year) =&amp;gt; ({&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;type: &#34;bar&#34;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;name: year,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;data: Object.values(amounts[year]),&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;label: {&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;show: false,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;formatter: (params) =&amp;gt; currencyFormatter(params.value),&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;})),&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;rocketchat&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/rocketchat/&#34;&gt;Rocketchat&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/rocketchat/#api&#34;&gt;How to use Rocketchat&#39;s API.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The API docs are a bit weird, you need to go to &lt;a href=&#34;https://developer.rocket.chat/reference/api/rest-api/endpoints&#34;&gt;endpoints&lt;/a&gt; and find the one you need. Your best bet though is to open the browser network console and see which requests they are doing and then to find them in the docs.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/rocketchat/#references&#34;&gt;Add end of life link.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Warning they only support 6 months of versions! and they advice you with 12 days that you&#39;ll loose service if you don&#39;t update.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://docs.rocket.chat/docs/version-durability&#34;&gt;End of life for the versions&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;content-management&#34;&gt;Content Management&lt;/h3&gt; &lt;h4 id=&#34;jellyfin&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/moonlight/&#34;&gt;Jellyfin&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce moonlight.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/moonlight-stream/moonlight-docs/wiki&#34;&gt;Moonlight&lt;/a&gt; is an open source client implementation of NVIDIA GameStream that allows you to to stream your collection of games and apps from your GameStream-compatible PC to another device on your network or the Internet. You can play your favorite games on your PC, phone, tablet, or TV with Moonlight..&lt;/p&gt; &lt;p&gt;References:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://moonlight-stream.org/&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/moonlight-stream/moonlight-docs/wiki&#34;&gt;Docs&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/#python-library&#34;&gt;Python library.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/jellyfin/jellyfin-apiclient-python/tree/master&#34;&gt;This is the API client&lt;/a&gt; from Jellyfin Kodi extracted as a python package so that other users may use the API without maintaining a fork of the API client. Please note that this API client is not complete. You may have to add API calls to perform certain tasks.&lt;/p&gt; &lt;p&gt;It doesn&#39;t (yet) support async&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/#system.invalidoperationexception:-there-is-an-error-in-xml-document-0,-0&#34;&gt;Troubleshoot pSystem.InvalidOperationException: There is an error in XML document (0, 0).&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This may happen if you run out of disk and some xml file in the jellyfin data directory becomes empty. The solution is to restore that file from backup.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/#enable-hardware-transcoding&#34;&gt;Enable hardware transcoding.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://jellyfin.org/docs/general/administration/hardware-acceleration/nvidia&#34;&gt;Enable NVIDIA hardware transcoding&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;Remove the artificial limit of concurrent NVENC transcodings&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Consumer targeted &lt;a href=&#34;https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-new&#34;&gt;Geforce and some entry-level Quadro cards&lt;/a&gt; have an artificial limit on the number of concurrent NVENC encoding sessions (max of 8 on most modern ones). This restriction can be circumvented by applying an unofficial patch to the NVIDIA Linux and Windows driver.&lt;/p&gt; &lt;p&gt;To apply the patch:&lt;/p&gt; &lt;p&gt;First check that your current version is supported &lt;code&gt;nvidia-smi&lt;/code&gt;, if it&#39;s not try to upgrade the drivers to a supported one, or think if you need more than 8 transcodings. &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;wget&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://raw.githubusercontent.com/keylase/nvidia-patch/refs/heads/master/patch.sh
chmod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;+x&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;patch.sh
./patch.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;If you need to rollback the changes run &lt;code&gt;./patch.sh -r&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;You can also patch it &lt;a href=&#34;https://github.com/keylase/nvidia-patch?tab=readme-ov-file#docker-support&#34;&gt;within the docker itself&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;jellyfin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;jellyfin/jellyfin&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;1000:1000&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;network_mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;host&#39;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/path/to/config:/config&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/path/to/cache:/cache&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/path/to/media:/media&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;runtime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;nvidia&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;deploy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;reservations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;devices&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;driver&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;nvidia&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;all&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;capabilities&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;gpu&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Restart the docker and then check that you can access the graphics card with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-it&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;jellyfin&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;nvidia-smi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Enable NVENC in Jellyfin and uncheck the unsupported codecs.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Tweak the docker-compose&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The official Docker image doesn&#39;t include any NVIDIA proprietary driver.&lt;/p&gt; &lt;p&gt;You have to install the NVIDIA driver and NVIDIA Container Toolkit on the host system to allow Docker access to your GPU.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;immich&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/ombi/&#34;&gt;Immich&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ombi/#set-default-quality-of-request-per-user&#34;&gt;Set default quality of request per user.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Sometimes one specific user continuously asks for a better quality of the content. If you go into the user configuration (as admin) you can set the default quality profiles for that user.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce immich.&lt;/p&gt; &lt;p&gt;Self-hosted photo and video backup solution directly from your mobile phone.&lt;/p&gt; &lt;p&gt;References:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://immich.app/&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://immich.app/docs/api&#34;&gt;Api&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://immich.app/docs/overview/introduction&#34;&gt;Docs&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/immich-app/immich&#34;&gt;Source&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://immich.app/blog&#34;&gt;Blog&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://demo.immich.app/photos&#34;&gt;Demo&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/immich/#installation&#34;&gt;Installation.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Create a directory of your choice (e.g. &lt;code&gt;./immich-app&lt;/code&gt;) to hold the &lt;code&gt;docker-compose.yml&lt;/code&gt; and &lt;code&gt;.env&lt;/code&gt; files.&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mkdir&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;./immich-app
&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;./immich-app
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Download &lt;code&gt;docker-compose.yml&lt;/code&gt;, &lt;code&gt;example.env&lt;/code&gt; and optionally the &lt;code&gt;hwaccel.yml&lt;/code&gt; files:&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;wget&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-O&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker-compose.yaml&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://github.com/immich-app/immich/releases/latest/download/dockr-compose.yml
wget&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-O&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.env&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://github.com/immich-app/immich/releases/latest/download/example.env
wget&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://github.com/immich-app/immich/releases/latest/download/hwaccel.yml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; - Tweak those files with these thoughts in mind: - &lt;code&gt;immich&lt;/code&gt; won&#39;t respect your upload media directory structure, so until you trust the softwar copy your media to the uploads directory. - immich is not stable so you need to disable the upgrade from watchtower. The easiest way is to &lt;a href=&#34;https://github.com/immich-app/immich/pkgs/container/immich-server/versions?filters%5Bversion_type%5D=tagged&#34;&gt;pin the latest stable version&lt;/a&gt; in the &lt;code&gt;.env&lt;/code&gt; file. - Populate custom database information if necessary. - Populate &lt;code&gt;UPLOAD_LOCATION&lt;/code&gt; with your preferred location for storing backup assets. - Consider changing &lt;code&gt;DB_PASSWORD&lt;/code&gt; to something randomly generated&lt;/p&gt; &lt;ul&gt; &lt;li&gt;From the directory you created in Step 1, (which should now contain your customized &lt;code&gt;docker-compose.yml&lt;/code&gt; and &lt;code&gt;.env&lt;/code&gt; files) run:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;compose&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;up&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/immich/#configure-smart-search-for-other-language&#34;&gt;Configure smart search for other language.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can change to a multilingual model listed &lt;a href=&#34;https://huggingface.co/collections/immich-app/multilingual-clip-654eb08c2382f591eeb8c2a7&#34;&gt;here&lt;/a&gt; by going to Administration &amp;gt; Machine Learning Settings &amp;gt; Smart Search and replacing the name of the model.&lt;/p&gt; &lt;p&gt;Choose the one that has more downloads. For example, if you&#39;d want the &lt;code&gt;+immich-app/XLM-Roberta-Large-Vit-B-16Plus&lt;/code&gt; model, you should only enter &lt;code&gt;XLM-Roberta-Large-Vit-B-16Plus&lt;/code&gt; in the program configuration. Be careful not to add trailing whitespaces.&lt;/p&gt; &lt;p&gt;Be sure to re-run Smart Search on all assets after this change. You can then search in over 100 languages.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/immich/#external-storage&#34;&gt;External storage.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you have an already existing library somewhere immich is installed you can use an &lt;a href=&#34;https://immich.app/docs/guides/external-library&#34;&gt;external library&lt;/a&gt;. Immich will respect the files on that directory.&lt;/p&gt; &lt;p&gt;It won&#39;t create albums from the directory structure. If you want to do that check &lt;a href=&#34;https://github.com/alvistar/immich-albums&#34;&gt;this&lt;/a&gt; or &lt;a href=&#34;https://gist.github.com/REDVM/d8b3830b2802db881f5b59033cf35702&#34;&gt;this&lt;/a&gt; solutions.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/immich/#my-personal-workflow&#34;&gt;My personal workflow.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I&#39;ve tailored a personal workflow given the next thoughts:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;I don&#39;t want to expose Immich to the world, at least until it&#39;s a stable product.&lt;/li&gt; &lt;li&gt;I already have in place a sync mechanism with &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/syncthing/&#34;&gt;syncthing&lt;/a&gt; for all the mobile stuff&lt;/li&gt; &lt;li&gt;I do want to still be able to share some albums with my friends and family.&lt;/li&gt; &lt;li&gt;I want some mobile directories to be cleaned after importing the data (for example the &lt;code&gt;camera/DCIM&lt;/code&gt;), but others should leave the files as they are after the import (OsmAnd+ notes).&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Ingesting the files:&lt;/p&gt; &lt;p&gt;As all the files I want to ingest are sent to the server through syncthing, I&#39;ve created a cron script that copies or moves the required files. Something like:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;date
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Updating the OsmAnd+ data&#39;&lt;/span&gt;
rsync&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-auhvEX&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--progress&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/data/apps/syncthing/data/Osmand/avnotes&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/data/media/pictures/unclassified

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Updating the Camera data&#39;&lt;/span&gt;
mv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/data/apps/syncthing/data/camera/Camera/*&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/data/media/pictures/unclassified/

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Cleaning laptop home&#39;&lt;/span&gt;
mv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/data/media/downloads/*jpeg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/data/media/downloads/*jpg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/data/media/downloads/*png&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/data/media/pictures/unclassified/
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where :&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;/data/media/pictures/unclassified&lt;/code&gt; is a subpath of my &lt;a href=&#34;#external-library&#34;&gt;external library&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;The last echo makes sure that the program exits with a return code of &lt;code&gt;0&lt;/code&gt;. The script is improbable as it only takes into account the happy path, and I&#39;ll silently miss errors on it&#39;s execution. But as a first iteration it will do the job.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Then run the script in a cron and log the output to &lt;a href=&#34;https://lyz-code.github.io/blue-book/journald/&#34;&gt;&lt;code&gt;journald&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;0 0 * * * /bin/bash /usr/local/bin/archive-photos.sh | /usr/bin/logger -t archive_fotos
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Make sure to configure the update library cron job to run after this script has ended.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/immich/#not-there-yet&#34;&gt;Not there yet.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;There are some features that are still lacking:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/immich-app/immich/discussions/1695&#34;&gt;Image rotation&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/immich-app/immich/discussions/1673&#34;&gt;Smart albums&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/immich-app/immich/discussions/3619&#34;&gt;Image rating&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/immich-app/immich/discussions/1651&#34;&gt;Tags&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/immich-app/immich/discussions/2073#discussioncomment-6584926&#34;&gt;Nested albums&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/immich-app/immich/discussions/1968&#34;&gt;Duplication management&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/immich-app/immich/discussions/3657&#34;&gt;Search guide&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/immich/#edit-an-image-metadata&#34;&gt;Edit an image metadata.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can&#39;t do it directly through the interface yet, use &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#Remove-image-metadata&#34;&gt;exiftool&lt;/a&gt; instead.&lt;/p&gt; &lt;p&gt;This is interesting to remove the geolocation of the images that are not yours&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/immich/#keyboard-shortcuts&#34;&gt;Keyboard shortcuts.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can press &lt;code&gt;?&lt;/code&gt; to see the shortcuts. Some of the most useful are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;f&lt;/code&gt;: Toggle favourite&lt;/li&gt; &lt;li&gt;&lt;code&gt;Shift+a&lt;/code&gt;: Archive element&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;mediatracker&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/mediatracker/&#34;&gt;Mediatracker&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/mediatracker/#api&#34;&gt;How to use the mediatracker API.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I haven&#39;t found a way to see the api docs from my own instance. Luckily you can browse it &lt;a href=&#34;https://bonukai.github.io/MediaTracker/&#34;&gt;at the official instance&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;You can create an application token on your user configuration. Then you can use it with something similar to:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-H&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Content-Type: application/json&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://mediatracker.your-domain.org/api/logs&lt;span class=&#34;se&#34;&gt;\?&lt;/span&gt;token&lt;span class=&#34;se&#34;&gt;\=&lt;/span&gt;your-token&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;jq
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce python library.&lt;/p&gt; &lt;p&gt;There is a &lt;a href=&#34;https://github.com/jonkristian/pymediatracker&#34;&gt;python library&lt;/a&gt; although it&#39;s doesn&#39;t (yet) have any documentation and the functionality so far is only to get information, not to push changes.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/mediatracker/#get-list-of-tv-shows&#34;&gt;Get list of tv shows.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;With &lt;code&gt;/api/items?mediaType=tv&lt;/code&gt; you can get a list of all tv shows with the next interesting fields:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;id&lt;/code&gt;: mediatracker id&lt;/li&gt; &lt;li&gt;&lt;code&gt;tmdbId&lt;/code&gt;:&lt;/li&gt; &lt;li&gt;&lt;code&gt;tvdbId&lt;/code&gt;:&lt;/li&gt; &lt;li&gt;&lt;code&gt;imdbId&lt;/code&gt;:&lt;/li&gt; &lt;li&gt;&lt;code&gt;title&lt;/code&gt;:&lt;/li&gt; &lt;li&gt;&lt;code&gt;lastTimeUpdated&lt;/code&gt;: epoch time&lt;/li&gt; &lt;li&gt;&lt;code&gt;lastSeenAt&lt;/code&gt;: epoch time&lt;/li&gt; &lt;li&gt;&lt;code&gt;seen&lt;/code&gt;: bool&lt;/li&gt; &lt;li&gt;&lt;code&gt;onWatchlist&lt;/code&gt;: bool&lt;/li&gt; &lt;li&gt;&lt;code&gt;firstUnwatchedEpisode&lt;/code&gt;:&lt;/li&gt; &lt;li&gt;&lt;code&gt;id&lt;/code&gt;: mediatracker episode id&lt;/li&gt; &lt;li&gt;&lt;code&gt;episodeNumber&lt;/code&gt;:&lt;/li&gt; &lt;li&gt;&lt;code&gt;seasonNumber&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;tvShowId&lt;/code&gt;:&lt;/li&gt; &lt;li&gt;&lt;code&gt;seasonId&lt;/code&gt;:&lt;/li&gt; &lt;li&gt;&lt;code&gt;lastAiredEpisode&lt;/code&gt;: same schema as before&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Then you can use the &lt;code&gt;api/details/{mediaItemId}&lt;/code&gt; endpoint to get all the information of all the episodes of each tv show.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/mediatracker/#add-missing-books&#34;&gt;Add missing books.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Register an account in openlibrary.com&lt;/li&gt; &lt;li&gt;Add the book&lt;/li&gt; &lt;li&gt;Then add it to mediatracker&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;ffmpeg&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/ffmpeg/&#34;&gt;ffmpeg&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ffmpeg/#reduce-the-video-size&#34;&gt;Reduce the video size.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you don&#39;t mind using &lt;code&gt;H.265&lt;/code&gt; replace the libx264 codec with libx265, and push the compression lever further by increasing the CRF value — add, say, 4 or 6, since a reasonable range for H.265 may be 24 to 30. Note that lower CRF values correspond to higher bitrates, and hence produce higher quality videos.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ffmpeg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;input.mp4&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-vcodec&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libx265&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-crf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;28&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output.mp4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you want to stick to H.264 reduce the bitrate. You can check the current one with &lt;code&gt;ffprobe input.mkv&lt;/code&gt;. Once you&#39;ve chosen the new rate change it with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ffmpeg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;input.mp4&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-b&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;3000k&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output.mp4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Additional options that might be worth considering is setting the Constant Rate Factor, which lowers the average bit rate, but retains better quality. Vary the CRF between around 18 and 24 — the lower, the higher the bitrate.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ffmpeg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;input.mp4&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-vcodec&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libx264&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-crf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output.mp4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;photo-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/photo_self_hosted/&#34;&gt;Photo management&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Do comparison of selfhosted photo software.&lt;/p&gt; &lt;p&gt;There are &lt;a href=&#34;https://awesome-selfhosted.net/tags/photo-and-video-galleries.html&#34;&gt;many alternatives to self host a photo management software&lt;/a&gt;, here goes my personal comparison. You should complement this article with &lt;a href=&#34;https://meichthys.github.io/foss_photo_libraries/&#34;&gt;meichthys one&lt;/a&gt;.&lt;/p&gt; &lt;div class=&#34;admonition note&#34;&gt; &lt;p class=&#34;admonition-title&#34;&gt;TL;DR: I&#39;d first go with Immich, then LibrePhotos and then LycheeOrg&lt;/p&gt; &lt;/div&gt; &lt;table&gt; &lt;thead&gt; &lt;tr&gt; &lt;th&gt;Software&lt;/th&gt; &lt;th&gt;Home-Gallery&lt;/th&gt; &lt;th&gt;Immich&lt;/th&gt; &lt;th&gt;LibrePhotos&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;UI&lt;/td&gt; &lt;td&gt;Fine&lt;/td&gt; &lt;td&gt;Good&lt;/td&gt; &lt;td&gt;Fine&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Popular (stars)&lt;/td&gt; &lt;td&gt;614&lt;/td&gt; &lt;td&gt;25k&lt;/td&gt; &lt;td&gt;6k&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Active (PR/Issues)(1)&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;251/231&lt;/td&gt; &lt;td&gt;27/16&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Easy deployment&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;Complicated&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Good docs&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Stable&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;False&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Smart search&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Language&lt;/td&gt; &lt;td&gt;Javascript&lt;/td&gt; &lt;td&gt;Typescript&lt;/td&gt; &lt;td&gt;Python&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Batch edit&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Multi-user&lt;/td&gt; &lt;td&gt;False&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Mobile app&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Oauth support&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Facial recognition&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Scales well&lt;/td&gt; &lt;td&gt;False&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Favourites&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Archive&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Has API&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Map support&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Video Support&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Discover similar&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Static site&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;False&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;ul&gt; &lt;li&gt;(1): It refers to the repository stats of the last month&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/immich/&#34;&gt;Immich&lt;/a&gt;&lt;/strong&gt;:&lt;/p&gt; &lt;p&gt;References:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://immich.app/&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://demo.immich.app/photos&#34;&gt;Demo&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/immich-app/immich&#34;&gt;Source&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Pros: - Smart search is awesome Oo - create shared albums that people can use to upload and download - map with leaflet - explore by people and places - docker compose - optional &lt;a href=&#34;https://immich.app/docs/features/hardware-transcoding&#34;&gt;hardware acceleration&lt;/a&gt; - very popular 25k stars, 1.1k forks - has a &lt;a href=&#34;https://immich.app/docs/features/command-line-interface&#34;&gt;CLI&lt;/a&gt; - can &lt;a href=&#34;https://immich.app/docs/features/libraries&#34;&gt;load data from a directory&lt;/a&gt; - It has an &lt;a href=&#34;https://immich.app/docs/features/mobile-app&#34;&gt;android app on fdroid to automatically upload media&lt;/a&gt; - &lt;a href=&#34;https://immich.app/docs/features/partner-sharing&#34;&gt;sharing libraries with other users&lt;/a&gt; and with the public - favorites and archive - public sharing - oauth2, specially with &lt;a href=&#34;https://immich.app/docs/administration/oauth&#34;&gt;authentik &amp;lt;3&lt;/a&gt; - extensive api: &lt;a href=&#34;https://immich.app/docs/api/introduction&#34;&gt;https://immich.app/docs/api/introduction&lt;/a&gt; - It has an UI similar to google photos, so it would be easy for non technical users to use. - Batch edit - Discover similar through the smart search&lt;/p&gt; &lt;p&gt;Cons:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;If you want to get results outside the smart search you are going to have a bad time. There is still no way to filter the smart search results or even sort them. You&#39;re sold to the AI.&lt;/li&gt; &lt;li&gt;dev suggests not to use watchtower as the project is in unstable alpha&lt;/li&gt; &lt;li&gt;Doesn&#39;t work well in firefox&lt;/li&gt; &lt;li&gt;It doesn&#39;t work with tags which you don&#39;t need because the smart search is so powerful.&lt;/li&gt; &lt;li&gt;Scans pictures on the file system&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://docs.librephotos.com/&#34;&gt;LibrePhotos&lt;/a&gt;&lt;/strong&gt;:&lt;/p&gt; &lt;p&gt;References:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/LibrePhotos/librephotos&#34;&gt;Source&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://docs.librephotos.com/docs/intro&#34;&gt;Docs&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://demo2.librephotos.com/login&#34;&gt;Demo&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://docs.librephotos.com/docs/user-guide/features&#34;&gt;Outdated comparison&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Pros:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://docs.librephotos.com/docs/installation/standard-install&#34;&gt;docker compose&lt;/a&gt;, although you need to build the dockers yourself&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://docs.librephotos.com/docs/user-guide/mobile/&#34;&gt;android app&lt;/a&gt;&lt;/li&gt; &lt;li&gt;6k stars, 267 forks&lt;/li&gt; &lt;li&gt;object, scene ai extraction&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Cons:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Not as good as Immich.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://docs.home-gallery.org/general.html&#34;&gt;Home-Gallery&lt;/a&gt;&lt;/strong&gt;:&lt;/p&gt; &lt;p&gt;You can see the demo &lt;a href=&#34;https://demo.home-gallery.org/&#34;&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Nice features:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Simple UI&lt;/li&gt; &lt;li&gt;Discover similar images&lt;/li&gt; &lt;li&gt;Static site generator&lt;/li&gt; &lt;li&gt;Shift click to do batch editing&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Cons:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;All users see all media&lt;/li&gt; &lt;li&gt;The whole database is loaded into the browser and requires recent (mobile) devices and internet connection&lt;/li&gt; &lt;li&gt;Current tested limits are about 400,000 images/videos&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Lycheeorg&lt;/strong&gt;:&lt;/p&gt; &lt;p&gt;References:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lycheeorg.github.io/&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lycheeorg.github.io/docs&#34;&gt;Docs&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/LycheeOrg/Lychee&#34;&gt;Source&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Pros:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Sharing like it should be. One click and every photo and album is ready for the public. You can also protect albums with passwords if you want. It&#39;s under your control.&lt;/li&gt; &lt;li&gt;Manual tags&lt;/li&gt; &lt;li&gt;apparently safe upgrades&lt;/li&gt; &lt;li&gt;docker compose&lt;/li&gt; &lt;li&gt;2.9k stars&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Cons: - demo doesn&#39;t show many features - no ai&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Photoview&lt;/strong&gt;:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://photoview.github.io/&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/photoview/photoview&#34;&gt;Source&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://photoview.github.io/en/docs/usage-people/&#34;&gt;Docs&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Pros:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Syncs with file system&lt;/li&gt; &lt;li&gt;Albums and individual photos or videos can easily be shared by generating a public or password protected link.&lt;/li&gt; &lt;li&gt;users support&lt;/li&gt; &lt;li&gt;maps support&lt;/li&gt; &lt;li&gt;4.4k stars&lt;/li&gt; &lt;li&gt;Face recognition&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Cons:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Demo difficult to understand as it&#39;s not in english&lt;/li&gt; &lt;li&gt;mobile app only for ios&lt;/li&gt; &lt;li&gt;last commit 6 months ago&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Pigallery2&lt;/strong&gt;:&lt;/p&gt; &lt;p&gt;References:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://bpatrik.github.io/pigallery2/&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Pros:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;map&lt;/li&gt; &lt;li&gt;The gallery also supports *.gpx file to show your tracked path on the map too&lt;/li&gt; &lt;li&gt;App supports full boolean logic with negation and exact or wildcard search. It also provides handy suggestions with autocomplete.&lt;/li&gt; &lt;li&gt;face recognitiom: PiGallery2 can read face reagions from photo metadata. Current limitation: No ML-based, automatic face detection.&lt;/li&gt; &lt;li&gt;rating and grouping by rating&lt;/li&gt; &lt;li&gt;easy query builder&lt;/li&gt; &lt;li&gt;video transcoding&lt;/li&gt; &lt;li&gt;blog support. Markdown based blogging support&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;You can write some note in the *.md files for every directory&lt;/p&gt; &lt;ul&gt; &lt;li&gt;You can create logical albums (a.k.a.: Saved search) from any search query. Current limitation: It is not possible to create albums from a manually picked photos.&lt;/li&gt; &lt;li&gt;PiGallery2 has a rich settings page where you can easily set up the gallery.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Cons: - no ml face recognition&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Piwigo&lt;/strong&gt;:&lt;/p&gt; &lt;p&gt;References:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;piwigo.org&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/Piwigo/Piwigo&#34;&gt;Source&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Piwigo is open source photo management software. Manage, organize and share your photo easily on the web. Designed for organisations, teams and individuals&lt;/p&gt; &lt;p&gt;Pros:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Thousands of organizations and millions of individuals love using Piwigo&lt;/li&gt; &lt;li&gt;shines when it comes to classifying thousands or even hundreds of thousands of photos.&lt;/li&gt; &lt;li&gt;Born in 2002, Piwigo has been supporting its users for more than 21 years. Always evolving!&lt;/li&gt; &lt;li&gt;You can add photos with the web form, any FTP client ora desktop application like digiKam, Shotwell, Lightroom ormobile applications.&lt;/li&gt; &lt;li&gt;Filter photos from your collection, make a selection and apply actions in batch: change the author, add some tags, associate to a new album, set geolocation...&lt;/li&gt; &lt;li&gt;Make your photos private and decide who can see each of them. You can set permissions on albums and photos, for groups or individual users.&lt;/li&gt; &lt;li&gt;Piwigo can read GPS latitude and longitude from embedded metadata. Then, with plugin for Google Maps or OpenStreetMap, Piwigo can display your photos on an interactive map.&lt;/li&gt; &lt;li&gt;Change appearance with themes. Add features with plugins. Extensions require just a few clicks to get installed. 350 extensions available, and growing!&lt;/li&gt; &lt;li&gt;With the Fotorama plugin, or specific themes such as Bootstrap Darkroom, you can experience the full screen slideshow.&lt;/li&gt; &lt;li&gt;Your visitors can post comments, give ratings, mark photos as favorite, perform searches and get notified of news by email.&lt;/li&gt; &lt;li&gt;Piwigo web API makes it easy for developers to perform actions from other applications&lt;/li&gt; &lt;li&gt;GNU General Public License, or GPL&lt;/li&gt; &lt;li&gt;2.9 k stars, 400 forks&lt;/li&gt; &lt;li&gt;still active&lt;/li&gt; &lt;li&gt;nice release documents: &lt;a href=&#34;https://piwigo.org/release-14.0.0&#34;&gt;https://piwigo.org/release-14.0.0&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Cons:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Official docs don&#39;t mention docker&lt;/li&gt; &lt;li&gt;no demo: &lt;a href=&#34;https://piwigo.org/demo&#34;&gt;https://piwigo.org/demo&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Unpleasant docs: &lt;a href=&#34;https://piwigo.org/doc/doku.php&#34;&gt;https://piwigo.org/doc/doku.php&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Awful plugin search: &lt;a href=&#34;https://piwigo.org/ext/&#34;&gt;https://piwigo.org/ext/&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://damselfly.info/&#34;&gt;Damselfly&lt;/a&gt;&lt;/strong&gt;:&lt;/p&gt; &lt;p&gt;Fast server-based photo management system for large collections of images. Includes face detection, face &amp;amp; object recognition, powerful search, and EXIF Keyword tagging. Runs on Linux, MacOS and Windows.&lt;/p&gt; &lt;p&gt;Very ugly UI&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/saimn/sigal&#34;&gt;Saigal&lt;/a&gt;&lt;/strong&gt;:&lt;/p&gt; &lt;p&gt;Too simple&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/gbbirkisson/spis&#34;&gt;Spis&lt;/a&gt;&lt;/strong&gt;:&lt;/p&gt; &lt;p&gt;Low number of maintainers Too simple&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;kodi&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/kodi/&#34;&gt;Kodi&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Start working on a migration script to mediatracker.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/kodi/#from-the-database&#34;&gt;Extract kodi data from the database.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;At &lt;code&gt;~/.kodi/userdata/Database/MyVideos116.db&lt;/code&gt; you can extract the data from the next tables:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;In the &lt;code&gt;movie_view&lt;/code&gt; table there is:&lt;/li&gt; &lt;li&gt;&lt;code&gt;idMovie&lt;/code&gt;: kodi id for the movie&lt;/li&gt; &lt;li&gt;&lt;code&gt;c00&lt;/code&gt;: Movie title&lt;/li&gt; &lt;li&gt;&lt;code&gt;userrating&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;uniqueid_value&lt;/code&gt;: The id of the external web service&lt;/li&gt; &lt;li&gt;&lt;code&gt;uniqueid_type&lt;/code&gt;: The web it extracts the id from&lt;/li&gt; &lt;li&gt;&lt;code&gt;lastPlayed&lt;/code&gt;: The reproduction date&lt;/li&gt; &lt;li&gt;In the &lt;code&gt;tvshow_view&lt;/code&gt; table there is:&lt;/li&gt; &lt;li&gt;&lt;code&gt;idShow&lt;/code&gt;: kodi id of a show&lt;/li&gt; &lt;li&gt;&lt;code&gt;c00&lt;/code&gt;: title&lt;/li&gt; &lt;li&gt;&lt;code&gt;userrating&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;lastPlayed&lt;/code&gt;: The reproduction date&lt;/li&gt; &lt;li&gt;&lt;code&gt;uniqueid_value&lt;/code&gt;: The id of the external web service&lt;/li&gt; &lt;li&gt;&lt;code&gt;uniqueid_type&lt;/code&gt;: The web it extracts the id from&lt;/li&gt; &lt;li&gt;In the &lt;code&gt;season_view&lt;/code&gt; there is no interesting data as the userrating is null on all rows.&lt;/li&gt; &lt;li&gt;In the &lt;code&gt;episode_view&lt;/code&gt; table there is:&lt;/li&gt; &lt;li&gt;&lt;code&gt;idEpisodie&lt;/code&gt;: kodi id for the episode&lt;/li&gt; &lt;li&gt;&lt;code&gt;idShow&lt;/code&gt;: kodi id of a show&lt;/li&gt; &lt;li&gt;`idSeason: kodi id of a season&lt;/li&gt; &lt;li&gt;&lt;code&gt;c00&lt;/code&gt;: title&lt;/li&gt; &lt;li&gt;&lt;code&gt;userrating&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;lastPlayed&lt;/code&gt;: The reproduction date&lt;/li&gt; &lt;li&gt;&lt;code&gt;uniqueid_value&lt;/code&gt;: The id of the external web service&lt;/li&gt; &lt;li&gt;&lt;code&gt;uniqueid_type&lt;/code&gt;: The web it extracts the id from. I&#39;ve seen mainly tvdb and sonarr&lt;/li&gt; &lt;li&gt;Don&#39;t use the &lt;code&gt;rating&lt;/code&gt; table as it only stores the ratings from external webs such as themoviedb:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;knowledge-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/knowledge_management/&#34;&gt;Knowledge Management&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Use ebops to create anki cards.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Ask the AI to generate &lt;a href=&#34;https://lyz-code.github.io/blue-book/anki/&#34;&gt;Anki cards&lt;/a&gt; based on the content.&lt;/li&gt; &lt;li&gt;Save those anki cards in an orgmode (&lt;code&gt;anki.org&lt;/code&gt;) document&lt;/li&gt; &lt;li&gt;Use &lt;a href=&#34;https://codeberg.org/lyz/ebops&#34;&gt;&lt;code&gt;ebops add-anki-notes&lt;/code&gt;&lt;/a&gt; to automatically add them to Anki&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;anki&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/anki/&#34;&gt;Anki&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/anki/#what-to-do-when-you-need-to-edit-a-card-but-don&#39;t-have-the-time&#34;&gt;What to do when you need to edit a card but don&#39;t have the time.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can mark it with a red flag so that you remember to edit it the next time you see it.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/mkdocs/#center-images&#34;&gt;Center images.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;In your config enable the &lt;code&gt;attr_list&lt;/code&gt; extension:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;markdown_extensions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;attr_list&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;On your &lt;code&gt;extra.css&lt;/code&gt; file add the &lt;code&gt;center&lt;/code&gt; class&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;center&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;block&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;margin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Now you can center elements by appending the attribute:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;![&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;](&lt;span class=&#34;na&#34;&gt;../_imatges/ebc_form_01.jpg&lt;/span&gt;){: .center}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/anki/#install-the-official-sync-server&#34;&gt;Install the official sync server.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;analytical-web-reading&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/analytical_web_reading/&#34;&gt;Analytical web reading&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Analytical web reading.&lt;/p&gt; &lt;p&gt;One part of the web 3.0 is to be able to annotate and share comments on the web. This article is my best try to find a nice open source privacy friendly tool. Spoiler: there aren&#39;t any :P&lt;/p&gt; &lt;p&gt;The alternative I&#39;m using so far is to process the data at the same time as I underline it.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;At the mobile/tablet you can split your screen and have Orgzly on one tab and the browser in the other. So that underlining, copy and paste doesn&#39;t break too much the workflow.&lt;/li&gt; &lt;li&gt;At the eBook I underline it and post process it after.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The idea of using an underlining tool makes sense in the case to post process the content in a more efficient environment such as a laptop.&lt;/p&gt; &lt;p&gt;The use of Orgzly is kind of a preprocessing. If the underlining software can easily export the highlighted content along with the link to the source then it would be much quicker&lt;/p&gt; &lt;p&gt;The advantage of using Orgzly is also that it works today both online and offline and it is more privacy friendly.&lt;/p&gt; &lt;p&gt;On the post I review some of the existent solutions&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;digital-gardens&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/digital_garden/&#34;&gt;Digital Gardens&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/digital_garden/#add-the-not-by-ai-badge&#34;&gt;Add the not by AI badge.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://notbyai.fyi/&#34;&gt;Not by AI&lt;/a&gt; is an initiative to mark content as created by humans instead of AI.&lt;/p&gt; &lt;p&gt;To automatically add the badge to all your content you can use the next script:&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Checking the Not by AI badge&#34;&lt;/span&gt;
find&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-iname&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;*md&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-print0&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;$&#39;\0&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;file&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;!&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-q&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;not-by-ai.svg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$file&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Adding the Not by AI badge to &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$file&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;[![](../img/not-by-ai.svg){: .center}](https://notbyai.fyi)&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&amp;gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$file&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; You can see how it&#39;s used in this blog by looking at the &lt;code&gt;Makefile&lt;/code&gt; and the &lt;code&gt;gh-pages.yaml&lt;/code&gt; workflow.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;aleph&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/&#34;&gt;Aleph&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/#monitorization&#34;&gt;Add note on aleph and prometheus.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Aleph now exposes prometheus metrics on the port 9100&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/#debug-ingestion-errors&#34;&gt;Debug ingestion errors.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Assuming that you&#39;ve &lt;a href=&#34;https://github.com/alephdata/aleph/issues/2124&#34;&gt;set up Loki to ingest your logs&lt;/a&gt; I&#39;ve so far encountered the next ingest issues:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;Cannot open image data using Pillow: broken data stream when reading image files&lt;/code&gt;: The log trace that has this message also contains a field &lt;code&gt;trace_id&lt;/code&gt; which identifies the ingestion process. With that &lt;code&gt;trace_id&lt;/code&gt; you can get the first log trace with the field &lt;code&gt;logger = &#34;ingestors.manager&#34;&lt;/code&gt; which will contain the file path in the &lt;code&gt;message&lt;/code&gt; field. Something similar to &lt;code&gt;Ingestor [&amp;lt;E(&#39;9972oiwobhwefoiwefjsldkfwefa45cf5cb585dc4f1471&#39;,&#39;path_to_the_file_to_ingest.pdf&#39;)&amp;gt;]&lt;/code&gt;&lt;/li&gt; &lt;li&gt;A traceback with the next string &lt;code&gt;Failed to process: Could not extract PDF file: FileDataError(&#39;cannot open broken document&#39;)&lt;/code&gt;: This log trace has the file path in the &lt;code&gt;message&lt;/code&gt; field. Something similar to &lt;code&gt;[&amp;lt;E(&#39;9972oiwobhwefoiwefjsldkfwefa45cf5cb585dc4f1471&#39;,&#39;path_to_the_file_to_ingest.pdf&#39;)&amp;gt;] Failed to process: Could not extract PDF file: FileDataError(&#39;cannot open broken document&#39;)&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;I thought of making a &lt;a href=&#34;https://lyz-code.github.io/blue-book/loki/#interact-with-loki-through-python&#34;&gt;python script to automate the files that triggered an error&lt;/a&gt;, but in the end I extracted the file names manually as they weren&#39;t many.&lt;/p&gt; &lt;p&gt;Once you have the files that triggered the errors, the best way to handle them is to delete them from your investigation and ingest them again.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/#references&#34;&gt;Add support channel.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://alephdata.slack.com&#34;&gt;Support chat&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/#api-usage&#34;&gt;API Usage.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The Aleph web interface is powered by a Flask HTTP API. Aleph supports an extensive API for searching documents and entities. It can also be used to retrieve raw metadata, source documents and other useful details. Aleph&#39;s API tries to follow a pragmatic approach based on the following principles:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;All API calls are prefixed with an API version; this version is /api/2/.&lt;/li&gt; &lt;li&gt;Responses and requests are both encoded as JSON. Requests should have the Content-Type and Accept headers set to application/json.&lt;/li&gt; &lt;li&gt;The application uses Representational State Transfer (REST) principles where convenient, but also has some procedural API calls.&lt;/li&gt; &lt;li&gt;The API allows API Authorization via an API key or JSON Web Tokens.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://redocly.github.io/redoc/?url=https://aleph.occrp.org/api/openapi.json#section/Authentication-and-Authorization&#34;&gt;Authentication and authorization&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;By default, any Aleph search will return only public documents in responses to API requests.&lt;/p&gt; &lt;p&gt;If you want to access documents which are not marked public, you will need to sign into the tool. This can be done through the use on an API key. The API key for any account can be found by clicking on the &#34;Profile&#34; menu item in the navigation menu.&lt;/p&gt; &lt;p&gt;The API key must be sent on all queries using the Authorization HTTP header:&lt;/p&gt; &lt;p&gt;Authorization: ApiKey 363af1e2b03b41c6b3adc604956e2f66&lt;/p&gt; &lt;p&gt;Alternatively, the API key can also be sent as a query parameter under the api_key key.&lt;/p&gt; &lt;p&gt;Similarly, a JWT can be sent in the Authorization header, after it has been returned by the login and/or OAuth processes. Aleph does not use session cookies or any other type of stateful API.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/#crossreferencing-mentions-with-entities&#34;&gt;Crossreferencing mentions with entities.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://docs.aleph.occrp.org/developers/explanation/cross-referencing/#mentions&#34;&gt;Mentions&lt;/a&gt; are names of people or companies that Aleph automatically extracts from files you upload. Aleph includes mentions when cross-referencing a collection, but only in one direction.&lt;/p&gt; &lt;p&gt;Consider the following example:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&#34;Collection A&#34; contains a file. The file mentions &#34;John Doe&#34;.&lt;/li&gt; &lt;li&gt;&#34;Collection B&#34; contains a Person entity named &#34;John Doe&#34;.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;If you cross-reference “Collection A”, Aleph includes the mention of “John Doe” in the cross-referencing and will find a match for it in “Collection B”.&lt;/p&gt; &lt;p&gt;However, if you cross-reference “Collection B”, Aleph doesn&#39;t consider mentions when trying to find a match for the Person entity.&lt;/p&gt; &lt;p&gt;As long as you only want to compare the mentions in one specific collection against entities (but not mentions) in another collection, Aleph’s cross-ref should be able to do that. If you want to compare entities in a specific collection against other entities and mentions in other collections, you will have to do that yourself.&lt;/p&gt; &lt;p&gt;If you have a limited number of collection, one option might be to fetch all mentions and automatically create entities for each mention using the API.&lt;/p&gt; &lt;p&gt;To fetch a list of mentions for a collection you can use the &lt;code&gt;/api/2/entities?filter:collection_id=137&amp;amp;filter:schemata=Mention&lt;/code&gt; API request.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/#alephclient-cli-tool&#34;&gt;Alephclient cli tool.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;alephclient is a command-line client for Aleph. It can be used to bulk import structured data and files and more via the API, without direct access to the server.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://docs.aleph.occrp.org/developers/how-to/data/install-alephclient/#how-to-install-the-alephclient-cli&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can now install &lt;code&gt;alephclient&lt;/code&gt; using pip although I recommend to use &lt;code&gt;pipx&lt;/code&gt; instead:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pipx&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;alephclient
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;code&gt;alephclient&lt;/code&gt; needs to know the URL of the Aleph instance to connect to. For privileged operations (e.g. accessing private datasets or writing data), it also needs your API key. You can find your API key in your user profile in the Aleph UI.&lt;/p&gt; &lt;p&gt;Both settings can be provided by setting the environment variables &lt;code&gt;ALEPHCLIENT_HOST&lt;/code&gt; and &lt;code&gt;ALEPHCLIENT_API_KEY&lt;/code&gt;, respectively, or by passing them in with &lt;code&gt;--host&lt;/code&gt; and &lt;code&gt;--api-key&lt;/code&gt; options.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ALEPHCLIENT_HOST&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;https://aleph.occrp.org/
&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ALEPHCLIENT_API_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;YOUR_SECRET_API_KEY
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can now start using &lt;code&gt;alephclient&lt;/code&gt; for example to upload an entire directory to Aleph.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://docs.aleph.occrp.org/developers/how-to/data/upload-directory/&#34;&gt;Upload an entire directory to Aleph&lt;/a&gt;&lt;/strong&gt; While you can upload multiple files and even entire directories at once via the Aleph UI, using the &lt;code&gt;alephclient&lt;/code&gt; CLI allows you to upload files in bulk much quicker and more reliable.&lt;/p&gt; &lt;p&gt;Run the following &lt;code&gt;alephclient&lt;/code&gt; command to upload an entire directory to Aleph:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;alephclient&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;crawldir&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--foreign-id&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wikileaks-cable&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/Users/sunu/data/cable
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This will upload all files in the directory &lt;code&gt;/Users/sunu/data/cable&lt;/code&gt; (including its subdirectories) into an investigation with the foreign ID &lt;code&gt;wikileaks-cable&lt;/code&gt;. If no investigation with this foreign ID exists, a new investigation is created (in theory, but it didn&#39;t work for me, so manually create the investigation and then copy it&#39;s foreign ID).&lt;/p&gt; &lt;p&gt;If you’d like to import data into an existing investigation and do not know its foreign ID, you can find the foreign ID in the Aleph UI. Navigate to the investigation homepage. The foreign ID is listed in the sidebar on the right.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/#other-tools-for-the-ecosystem&#34;&gt;Other tools for the ecosystem.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/#available-datasets&#34;&gt;Available datasets.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;OpenSanctions helps investigators find leads, allows companies to manage risk and enables technologists to build data-driven products.&lt;/p&gt; &lt;p&gt;You can check &lt;a href=&#34;https://www.opensanctions.org/datasets/&#34;&gt;their datasets&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/#offshore-graph&#34;&gt;Offshore-graph.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/opensanctions/offshore-graph&#34;&gt;offshore-graph&lt;/a&gt; contains scripts that will merge the OpenSanctions Due Diligence dataset with the ICIJ OffshoreLeaks database in order create a combined graph for analysis.&lt;/p&gt; &lt;p&gt;The result is a Cypher script to load the full graph into the Neo4J database and then browse it using the Linkurious investigation platform.&lt;/p&gt; &lt;p&gt;Based on name-based entity matching between the datasets, an analyst can use this graph to find offshore holdings linked to politically exposed and sanctioned individuals.&lt;/p&gt; &lt;p&gt;As a general alternative, you can easily export and convert entities from an Aleph instance to visualize them in Neo4j or Gephi using the ftm CLI: &lt;a href=&#34;https://docs.aleph.occrp.org/developers/how-to/data/export-network-graphs/&#34;&gt;https://docs.aleph.occrp.org/developers/how-to/data/export-network-graphs/&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;torrent-management&#34;&gt;Torrent management&lt;/h3&gt; &lt;h4 id=&#34;qbittorrent&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/qbittorrent/&#34;&gt;qBittorrent&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/qbittorrent/#trackers-stuck-on-updating&#34;&gt;Troubleshoot Trackers stuck on Updating.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Sometimes the issue comes from an improvable configuration. In advanced:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Ensure that there are enough &lt;a href=&#34;https://github.com/qbittorrent/qBittorrent/issues/15744&#34;&gt;Max concurrent http announces&lt;/a&gt;: I changed from 50 to 500&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/qbittorrent/qBittorrent/issues/14453&#34;&gt;Select the correct interface and Optional IP address to bind to&lt;/a&gt;. In my case I selected &lt;code&gt;tun0&lt;/code&gt; as I&#39;m using a vpn and &lt;code&gt;All IPv4 addresses&lt;/code&gt; as I don&#39;t use IPv6.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;unpackerr&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/unpackerr/&#34;&gt;Unpackerr&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/unpackerr/#completed-item-still-waiting-no-extractable-files-found-at&#34;&gt;Completed item still waiting no extractable files found at.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This trace in the logs (which is super noisy) is not to worry.&lt;/p&gt; &lt;p&gt;Unpackerr is just telling you something is stuck in your sonar queue. It&#39;s not an error, and it&#39;s not trying to extract it (because it has no compressed files). The fix is to figure out why it&#39;s stuck in the queue.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;health&#34;&gt;Health&lt;/h2&gt; &lt;h3 id=&#34;teeth&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/teeth/&#34;&gt;Teeth&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Suggestion on how to choose the toothpaste to buy.&lt;/p&gt; &lt;p&gt;When choosing a toothpaste choose the one that has a higher percent of fluoride.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;coding&#34;&gt;Coding&lt;/h2&gt; &lt;h3 id=&#34;languages&#34;&gt;Languages&lt;/h3&gt; &lt;h4 id=&#34;bash-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/&#34;&gt;Bash snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/#show-the-progresion-of-a-long-running-task-with-dots&#34;&gt;Show the progresion of a long running task with dots.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Process X is running.&#34;&lt;/span&gt;

sleep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;.&#34;&lt;/span&gt;
sleep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;.&#34;&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/#self-delete-shell-script&#34;&gt;Self delete shell script.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Add at the end of the script&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;rm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$0&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;code&gt;$0&lt;/code&gt; is a magic variable for the full path of the executed script.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/#add-a-user-to-the-sudoers-through-command-line-&#34;&gt;Add a user to the sudoers through command line.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Add the user to the sudo group:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;usermod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-G&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;username&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The change will take effect the next time the user logs in.&lt;/p&gt; &lt;p&gt;This works because &lt;code&gt;/etc/sudoers&lt;/code&gt; is pre-configured to grant permissions to all members of this group (You should not have to make any changes to this):&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;%sudo&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ALL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=(&lt;/span&gt;ALL:ALL&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ALL
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/#error-management-done-well-in-bash&#34;&gt;Error management done well in bash.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you wish to capture error management in bash you can use the next format&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;!&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$EMAIL&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$USER_TOTP_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;** Error: could not associate email for user &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$USERNAME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/#compare-two-semantic-versions&#34;&gt;Compare two semantic versions.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.baeldung.com/linux/compare-dot-separated-version-string&#34;&gt;This article&lt;/a&gt; gives a lot of ways to do it. For my case the simplest is to use &lt;code&gt;dpkg&lt;/code&gt; to compare two strings in dot-separated version format in bash.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Usage:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dpkg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--compare-versions&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;condition&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If the condition is &lt;code&gt;true&lt;/code&gt;, the status code returned by &lt;code&gt;dpkg&lt;/code&gt; will be zero (indicating success). So, we can use this command in an &lt;code&gt;if&lt;/code&gt; statement to compare two version numbers: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;dpkg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--compare-versions&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;2.11&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;lt&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;3&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;true&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;false&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/#exclude-list-of-extensions-from-find-command-&#34;&gt;Exclude list of extensions from find command.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;find&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-not&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;*.sh&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;*.log&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/#do-relative-import-of-a-bash-library&#34;&gt;Do relative import of a bash library.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you want to import a file &lt;code&gt;lib.sh&lt;/code&gt; that lives in the same directory as the file that is importing it you can use the next snippet:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;dirname&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;realpath&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$0&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/lib.sh&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you use &lt;code&gt;source ./lib.sh&lt;/code&gt; you will get an import error if you run the script on any other place that is not the directory where &lt;code&gt;lib.sh&lt;/code&gt; lives.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/#check-the-battery-status&#34;&gt;Check the battery status.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This &lt;a href=&#34;https://www.howtogeek.com/810971/how-to-check-a-linux-laptops-battery-from-the-command-line/&#34;&gt;article gives many ways to check the status of a battery&lt;/a&gt;, for my purposes the next one is enough&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/sys/class/power_supply/BAT0/capacity
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; feat(bash_snippets#Check if file is being sourced): Check if file is being sourced&lt;/p&gt; &lt;p&gt;Assuming that you are running bash, put the following code near the start of the script that you want to be sourced but not executed:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;BASH_SOURCE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[0]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-ef&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$0&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Hey, you should source this script, not execute it!&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Under bash, &lt;code&gt;${BASH_SOURCE[0]}&lt;/code&gt; will contain the name of the current file that the shell is reading regardless of whether it is being sourced or executed.&lt;/p&gt; &lt;p&gt;By contrast, &lt;code&gt;$0&lt;/code&gt; is the name of the current file being executed.&lt;/p&gt; &lt;p&gt;&lt;code&gt;-ef&lt;/code&gt; tests if these two files are the same file. If they are, we alert the user and exit.&lt;/p&gt; &lt;p&gt;Neither &lt;code&gt;-ef&lt;/code&gt; nor &lt;code&gt;BASH_SOURCE&lt;/code&gt; are POSIX. While &lt;code&gt;-ef&lt;/code&gt; is supported by ksh, yash, zsh and Dash, BASH_SOURCE requires bash. In zsh, however, &lt;code&gt;${BASH_SOURCE[0]}&lt;/code&gt; could be replaced by &lt;code&gt;${(%):-%N}&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/#parsing-bash-arguments&#34;&gt;Parsing bash arguments.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Long story short, it&#39;s nasty, think of using a python script with &lt;a href=&#34;https://lyz-code.github.io/blue-book/typer/&#34;&gt;typer&lt;/a&gt; instead.&lt;/p&gt; &lt;p&gt;There are some possibilities to do this:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.baeldung.com/linux/bash-parse-command-line-arguments&#34;&gt;The old getops&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/matejak/argbash&#34;&gt;argbash&lt;/a&gt; library&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://medium.com/@Drew_Stokes/bash-argument-parsing-54f3b81a6a8f&#34;&gt;Build your own parser&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/#fix-docker-error:-keyerror-containerconfig&#34;&gt;Fix docker error: KeyError ContainerConfig.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You need to run &lt;code&gt;docker-compose down&lt;/code&gt; and then up again.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/#set-static-ip-with-nmcli&#34;&gt;Set static ip with nmcli.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;nmcli&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;con&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;your-ssid&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ipv4.addresses
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;ipv4.method&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;manual&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;ipv4.addresses&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;your_desired_ip&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;ipv4.gateway&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;your_desired_gateway&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;ipv4.dns&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;1.1.1.1,2.2.2.2&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;ipv4.routes&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;192.168.32.0 0.0.0.0&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The last one is to be able to connect to your LAN, change the value accordingly.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/#fix-unbound-variable-error&#34;&gt;Fix unbound variable error.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can check if the variable is set and non-empty with: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;myvariable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/#with-sort&#34;&gt;Compare two semantic versions with sort.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you want to make it work in non-Debian based systems you can use &lt;code&gt;sort -V -C&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;2.0.0\n2.1.0\n&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sort&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-V&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-C&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Return code 0&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;2.2.0\n2.1.0\n&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sort&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-V&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-C&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Return code 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;bash-testing&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/bats/&#34;&gt;Bash testing&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce bats.&lt;/p&gt; &lt;p&gt;Bash Automated Testing System is a TAP-compliant testing framework for Bash 3.2 or above. It provides a simple way to verify that the UNIX programs you write behave as expected.&lt;/p&gt; &lt;p&gt;A Bats test file is a Bash script with special syntax for defining test cases. Under the hood, each test case is just a function with a description.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;@test&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;addition using bc&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;+2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;bc&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$result&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-eq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

@test&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;addition using dc&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;+p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dc&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$result&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-eq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Bats is most useful when testing software written in Bash, but you can use it to test any UNIX program.&lt;/p&gt; &lt;p&gt;References: - &lt;a href=&#34;https://github.com/bats-core/bats-core&#34;&gt;Source&lt;/a&gt; - &lt;a href=&#34;https://bats-core.readthedocs.io/&#34;&gt;Docs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;aiocron&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aiocron/&#34;&gt;aiocron&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce aiocron.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/gawel/aiocron?tab=readme-ov-file&#34;&gt;&lt;code&gt;aiocron&lt;/code&gt;&lt;/a&gt; is a python library to run cron jobs in python asyncronously.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can run it using a decorator&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;aiocron&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;asyncio&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nd&#34;&gt;@aiocron&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crontab&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;*/30 * * * *&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;attime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;     &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;run&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_event_loop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run_forever&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Or by calling the function yourself&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cron&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;crontab&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;0 * * * *&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yourcoroutine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;a href=&#34;https://stackoverflow.com/questions/65551736/python-3-9-scheduling-periodic-calls-of-async-function-with-different-paramete&#34;&gt;Here&#39;s a simple example&lt;/a&gt; on how to run it in a script:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;asyncio&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;datetime&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;aiocron&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;param&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;param&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;cron_min&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;aiocron&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crontab&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;*/1 * * * *&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;At every minute&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;cron_hour&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;aiocron&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crontab&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;0 */1 * * *&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;At minute 0 past every hour.&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;cron_day&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;aiocron&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crontab&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;0 9 */1 * *&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;At 09:00 on every day-of-month&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;cron_week&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;aiocron&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crontab&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;0 9 * * Mon&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;At 09:00 on every Monday&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sleep&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You have more complex examples &lt;a href=&#34;https://github.com/gawel/aiocron/tree/master/examples&#34;&gt;in the repo&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;aiocron
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt; - &lt;a href=&#34;https://github.com/gawel/aiocron?tab=readme-ov-file&#34;&gt;Source&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;configure-docker-to-host-the-application&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/lua/&#34;&gt;Configure Docker to host the application&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/lua/#inspect-contents-of-lua-table-in-neovim&#34;&gt;Inspect contents of Lua table in Neovim.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;When using Lua inside of Neovim you may need to view the contents of Lua tables, which are a first class data structure in Lua world. Tables in Lua can represent ordinary arrays, lists, symbol tables, sets, records, graphs, trees, etc.&lt;/p&gt; &lt;p&gt;If you try to just print a table directly, you will get the reference address for that table instead of the content, which is not very useful for most debugging purposes:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lua&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_get_mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;span class=&#34;s2&#34;&gt;&#34; table: 0x7f5b93e5ff88&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To solve this, Neovim provides the &lt;code&gt;vim.inspect&lt;/code&gt; function as part of its API. It serializes the content of any Lua object into a human readable string.&lt;/p&gt; &lt;p&gt;For example you can get information about the current mode like so:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lua&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inspect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_get_mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()))&lt;/span&gt;
&lt;span class=&#34;s2&#34;&gt;&#34; {  blocking = false,  mode = &#34;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#send-logs-to-journald&#34;&gt;Send logs to journald.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The &lt;code&gt;journald&lt;/code&gt; logging driver sends container logs to the systemd journal. Log entries can be retrieved using the &lt;code&gt;journalctl&lt;/code&gt; command, through use of the journal API, or using the docker logs command.&lt;/p&gt; &lt;p&gt;In addition to the text of the log message itself, the &lt;code&gt;journald&lt;/code&gt; log driver stores the following metadata in the journal with each message: | Field | Description | | --- | ---- | | CONTAINER_ID | The container ID truncated to 12 characters. | | CONTAINER_ID_FULL | The full 64-character container ID. | | CONTAINER_NAME | The container name at the time it was started. If you use docker rename to rename a container, the new name isn&#39;t reflected in the journal entries. | | CONTAINER_TAG, | SYSLOG_IDENTIFIER The container tag ( log tag option documentation). | | CONTAINER_PARTIAL_MESSAGE | A field that flags log integrity. Improve logging of long log lines. |&lt;/p&gt; &lt;p&gt;To use the journald driver as the default logging driver, set the log-driver and log-opts keys to appropriate values in the &lt;code&gt;daemon.json&lt;/code&gt; file, which is located in &lt;code&gt;/etc/docker/&lt;/code&gt;.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;log-driver&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;journald&#34;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Restart Docker for the changes to take effect.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#send-the-logs-to-loki&#34;&gt;Send the logs to loki.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;There are many ways to send logs to loki&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Using the json driver and sending them to loki with promtail with the docker driver&lt;/li&gt; &lt;li&gt;Using the docker plugin: Grafana Loki officially supports a Docker plugin that will read logs from Docker containers and ship them to Loki.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;I would not recommend to use this path because there is a known issue that deadlocks the docker daemon :S. The driver keeps all logs in memory and will drop log entries if Loki is not reachable and if the quantity of &lt;code&gt;max_retries&lt;/code&gt; has been exceeded. To avoid the dropping of log entries, setting &lt;code&gt;max_retries&lt;/code&gt; to zero allows unlimited retries; the driver will continue trying forever until Loki is again reachable. Trying forever may have undesired consequences, because the Docker daemon will wait for the Loki driver to process all logs of a container, until the container is removed. Thus, the Docker daemon might wait forever if the container is stuck.&lt;/p&gt; &lt;p&gt;The wait time can be lowered by setting &lt;code&gt;loki-retries=2&lt;/code&gt;, &lt;code&gt;loki-max-backoff_800ms&lt;/code&gt;, &lt;code&gt;loki-timeout=1s&lt;/code&gt; and &lt;code&gt;keep-file=true&lt;/code&gt;. This way the daemon will be locked only for a short time and the logs will be persisted locally when the Loki client is unable to re-connect.&lt;/p&gt; &lt;p&gt;To avoid this issue, use the Promtail Docker service discovery. - Using the journald driver and sending them to loki with promtail with the journald driver. This has worked for me but the labels extracted are not that great.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#syslog-getting-filled-up-with-docker-network-recreation&#34;&gt;Solve syslog getting filled up with docker network recreation.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you find yourself with your syslog getting filled up by lines similar to:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt; Jan 15 13:19:19 home kernel: [174716.097109] eth2: renamed from veth0adb07e
 Jan 15 13:19:20 home kernel: [174716.145281] IPv6: ADDRCONF(NETDEV_CHANGE): vethcd477bc: link becomes ready
 Jan 15 13:19:20 home kernel: [174716.145337] br-1ccd0f48be7c: port 5(vethcd477bc) entered blocking state
 Jan 15 13:19:20 home kernel: [174716.145338] br-1ccd0f48be7c: port 5(vethcd477bc) entered forwarding state
 Jan 15 13:19:20 home kernel: [174717.081132] br-fbe765bc7d0a: port 2(veth31cdd6f) entered disabled state
 Jan 15 13:19:20 home kernel: [174717.081176] vethc4da041: renamed from eth0
 Jan 15 13:19:21 home kernel: [174717.214911] br-fbe765bc7d0a: port 2(veth31cdd6f) entered disabled state
 Jan 15 13:19:21 home kernel: [174717.215917] device veth31cdd6f left promiscuous mode
 Jan 15 13:19:21 home kernel: [174717.215919] br-fbe765bc7d0a: port 2(veth31cdd6f) entered disabled state
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;It probably means that some docker is getting recreated continuously. Those traces are normal logs of docker creating the networks, but as they do each time the docker starts, if it&#39;s restarting continuously then you have a problem.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#minify-the-images&#34;&gt;Minify the images.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/wagoodman/dive&#34;&gt;dive&lt;/a&gt; and &lt;a href=&#34;https://github.com/slimtoolkit/slim&#34;&gt;slim&lt;/a&gt; are two cli tools you can use to optimise the size of your dockers.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;logging&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/python_logging/&#34;&gt;Logging&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/python_logging/#configure-the-logging-module-to-log-directly-to-systemd&#39;s-journal&#34;&gt;Configure the logging module to log directly to systemd&#39;s journal.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To use &lt;code&gt;systemd.journal&lt;/code&gt; in Python, you need to install the &lt;code&gt;systemd-python&lt;/code&gt; package. This package provides bindings for systemd functionality.&lt;/p&gt; &lt;p&gt;Install it using pip:&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;systemd-python
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; Below is an example Python script that configures logging to send messages to the systemd journal:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;logging&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;systemd.journal&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JournalHandler&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getLogger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;my_app&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setLevel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DEBUG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# Set the logging level&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;journal_handler&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JournalHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;journal_handler&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setLevel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DEBUG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# Adjust logging level if needed&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;journal_handler&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;addFilter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;record&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;setattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;record&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;SYSLOG_IDENTIFIER&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;mbsync_syncer&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;formatter&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Formatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%(asctime)s&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt; - &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%(name)s&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt; - &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%(levelname)s&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt; - &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%(message)s&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;journal_handler&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setFormatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;formatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;addHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;journal_handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;This is an info message.&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;This is an error message.&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;debug&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Debugging information.&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;When you run the script, the log messages will be sent to the systemd journal. You can view them using the &lt;code&gt;journalctl&lt;/code&gt; command:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;journalctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This command will show the latest log entries in real time. You can filter by your application name using:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;journalctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;my_app
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Replace &lt;code&gt;my_app&lt;/code&gt; with the logger name you used (e.g., &lt;code&gt;&#39;my_app&#39;&lt;/code&gt;).&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Additional Tips&lt;/strong&gt; - &lt;strong&gt;Tagging&lt;/strong&gt;: You can add a custom identifier for your logs by setting &lt;code&gt;logging.getLogger(&#39;your_tag&#39;)&lt;/code&gt;. This will allow you to filter logs using &lt;code&gt;journalctl -t your_tag&lt;/code&gt;. - &lt;strong&gt;Log Levels&lt;/strong&gt;: You can control the verbosity of the logs by setting different levels (e.g., &lt;code&gt;DEBUG&lt;/code&gt;, &lt;code&gt;INFO&lt;/code&gt;, &lt;code&gt;WARNING&lt;/code&gt;, &lt;code&gt;ERROR&lt;/code&gt;, &lt;code&gt;CRITICAL&lt;/code&gt;).&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Example Output in the Systemd Journal&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You should see entries similar to the following in the systemd journal:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Nov 15 12:45:30 my_hostname my_app[12345]: 2024-11-15 12:45:30,123 - my_app - INFO - This is an info message.
Nov 15 12:45:30 my_hostname my_app[12345]: 2024-11-15 12:45:30,124 - my_app - ERROR - This is an error message.
Nov 15 12:45:30 my_hostname my_app[12345]: 2024-11-15 12:45:30,125 - my_app - DEBUG - Debugging information.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This approach ensures that your logs are accessible through standard systemd tools and are consistent with other system logs. Let me know if you have any additional requirements or questions!&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;sqlite&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/boto3/&#34;&gt;SQLite&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/boto3/#get-running-instances&#34;&gt;Get running instances.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;boto3&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;ec2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;boto3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;ec2&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;running_instances&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;instance&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;page&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ec2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_paginator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;describe_instances&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;paginate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;reservation&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Reservations&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;instance&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;reservation&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Instances&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;instance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;State&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;][&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Name&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;running&#39;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/sqlite/#order-by-a-column-descending&#34;&gt;Order by a column descending.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;select_list&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;table&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;ORDER&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BY&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;column_1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ASC&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;column_2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;DESC&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;protocols&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/python_protocols/&#34;&gt;Protocols&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Python Protocols.&lt;/p&gt; &lt;p&gt;The Python type system supports two ways of deciding whether two objects are compatible as types: nominal subtyping and structural subtyping.&lt;/p&gt; &lt;p&gt;Nominal subtyping is strictly based on the class hierarchy. If class Dog inherits class &lt;code&gt;Animal&lt;/code&gt;, it’s a subtype of &lt;code&gt;Animal&lt;/code&gt;. Instances of &lt;code&gt;Dog&lt;/code&gt; can be used when &lt;code&gt;Animal&lt;/code&gt; instances are expected. This form of subtyping subtyping is what Python’s type system predominantly uses: it’s easy to understand and produces clear and concise error messages, and matches how the native &lt;code&gt;isinstance&lt;/code&gt; check works – based on class hierarchy.&lt;/p&gt; &lt;p&gt;Structural subtyping is based on the operations that can be performed with an object. Class &lt;code&gt;Dog&lt;/code&gt; is a structural subtype of class &lt;code&gt;Animal&lt;/code&gt; if the former has all attributes and methods of the latter, and with compatible types.&lt;/p&gt; &lt;p&gt;Structural subtyping can be seen as a static equivalent of duck typing, which is well known to Python programmers. See &lt;a href=&#34;https://peps.python.org/pep-0544/&#34;&gt;PEP 544&lt;/a&gt; for the detailed specification of protocols and structural subtyping in Python.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can define your own protocol class by inheriting the special Protocol class:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;typing&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Iterable&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;typing_extensions&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Protocol&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;SupportsClose&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Protocol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;# Empty method body (explicit &#39;...&#39;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Resource&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# No SupportsClose base class!&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
       &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;resource&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;release&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;# ... other methods ...&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;close_all&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;items&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Iterable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SupportsClose&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;item&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;items&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;close_all&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Resource&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;some/file&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)])&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# OK&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;code&gt;Resource&lt;/code&gt; is a subtype of the &lt;code&gt;SupportsClose&lt;/code&gt; protocol since it defines a compatible close method. Regular file objects returned by &lt;code&gt;open()&lt;/code&gt; are similarly compatible with the protocol, as they support &lt;code&gt;close()&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;If you want to define a docstring on the method use the next syntax:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Optional&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Load a configuration file.&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://mypy.readthedocs.io/en/stable/protocols.html#using-isinstance-with-protocols&#34;&gt;Make protocols work with &lt;code&gt;isinstance&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt; To check an instance against the protocol using &lt;code&gt;isinstance&lt;/code&gt;, we need to decorate our protocol with &lt;code&gt;@runtime_checkable&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://mypy.readthedocs.io/en/stable/protocols.html#invariance-of-protocol-attributes&#34;&gt;Make a protocol property variable&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://mypy.readthedocs.io/en/stable/protocols.html#callback-protocols&#34;&gt;Make protocol of functions&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt; - &lt;a href=&#34;https://mypy.readthedocs.io/en/stable/protocols.html&#34;&gt;Mypy article on protocols&lt;/a&gt; - &lt;a href=&#34;https://mypy.readthedocs.io/en/stable/protocols.html#predefined-protocol-reference&#34;&gt;Predefined protocols reference&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;logql&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/logql/&#34;&gt;Logql&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/logql/#compare-the-values-of-a-metric-with-the-past&#34;&gt;Compare the values of a metric with the past.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The offset modifier allows changing the time offset for individual range vectors in a query.&lt;/p&gt; &lt;p&gt;For example, the following expression counts all the logs within the last ten minutes to five minutes rather than last five minutes for the MySQL job. Note that the offset modifier always needs to follow the range vector selector immediately.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;count_over_time({job=&#34;mysql&#34;}[5m] offset 5m) // GOOD
count_over_time({job=&#34;mysql&#34;}[5m]) offset 5m // INVALID
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;fastapi&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/&#34;&gt;FastAPI&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Launch the server from within python.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;uvicorn&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;__main__&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;uvicorn&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;main:app&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;host&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;0.0.0.0&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;8000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;reload&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add the request time to the logs.&lt;/p&gt; &lt;p&gt;For more information on changing the logging read &lt;a href=&#34;https://nuculabs.dev/p/fastapi-uvicorn-logging-in-production&#34;&gt;1&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To set the datetime of the requests &lt;a href=&#34;https://stackoverflow.com/questions/62894952/fastapi-gunicon-uvicorn-access-log-format-customization&#34;&gt;use this configuration&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nd&#34;&gt;@asynccontextmanager&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;lifespan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FastAPI&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getLogger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;uvicorn.access&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;console_formatter&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;uvicorn&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ColourizedFormatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{asctime}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{levelprefix}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; : &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{message}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;style&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;{&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;use_colors&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;handlers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setFormatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;console_formatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;yield&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FastAPI&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lifespan&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lifespan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;graphql&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/graphql/&#34;&gt;Graphql&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce GraphQL.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://graphql.org/&#34;&gt;GraphQL&lt;/a&gt; is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.&lt;/p&gt; &lt;p&gt;To use it with python you can use &lt;a href=&#34;https://ariadnegraphql.org/&#34;&gt;Ariadne&lt;/a&gt; (&lt;a href=&#34;https://github.com/mirumee/ariadne&#34;&gt;source&lt;/a&gt;)&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pytest&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pytest/&#34;&gt;Pytest&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pytest/#changing-the-directory-when-running-tests-but-switching-it-back-after-the-test-ends&#34;&gt;Changing the directory when running tests but switching it back after the test ends.&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;nodejs&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/nodejs/&#34;&gt;nodejs&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/nodejs/#using-nvm&#34;&gt;Install using nvm.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o-&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;bash

nvm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;22&lt;/span&gt;

node&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# should print `v22.12.0`&lt;/span&gt;

npm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# should print `10.9.0`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;python-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/&#34;&gt;Python Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-unique-items-between-two-lists&#34;&gt;Get unique items between two lists.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you want all items from the second list that do not appear in the first list you can write:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;x = [1,2,3,4]
f = [1,11,22,33,44,3,4]

result = set(f) - set(x)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#pad-number-with-zeros&#34;&gt;Pad number with zeros.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;number&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;number&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;02d&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#parse-a-datetime-from-an-epoch&#34;&gt;Parse a datetime from an epoch.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;datetime&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fromtimestamp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1347517370&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;strftime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%c&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;s1&#34;&gt;&#39;2012-09-13 02:22:50&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#fix-variable-is-unbound-pyright-error&#34;&gt;Fix variable is unbound pyright error.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You may receive these warnings if you set variables inside if or try/except blocks such as the next one:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;  &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# &#34;a&#34; is possibly unbound&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The easy fix is to set &lt;code&gt;a = None&lt;/code&gt; outside those blocks&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;  &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# &#34;a&#34; is possibly unbound&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#investigate-a-class-attributes&#34;&gt;Investigate a class attributes.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://docs.python.org/3/library/inspect.html&#34;&gt;Investigate a class attributes with inspect&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#expire-the-cache-of-the-lru_cache&#34;&gt;Expire the cache of the lru_cache.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The &lt;code&gt;lru_cache&lt;/code&gt; decorator caches forever, a way to prevent it is by adding one more parameter to your expensive function: &lt;code&gt;ttl_hash=None&lt;/code&gt;. This new parameter is so-called &#34;time sensitive hash&#34;, its the only purpose is to affect lru_cache. For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;functools&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;lru_cache&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;time&lt;/span&gt;

&lt;span class=&#34;nd&#34;&gt;@lru_cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;my_expensive_function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ttl_hash&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;del&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ttl_hash&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# to emphasize we don&#39;t use it and to shut pylint up&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# horrible CPU load...&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;get_ttl_hash&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seconds&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3600&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Return the same value withing `seconds` time period&#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;round&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;seconds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;res&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;my_expensive_function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ttl_hash&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_ttl_hash&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#kill-a-process-by-it&#39;s-pid&#34;&gt;Kill a process by it&#39;s PID.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;signal&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kill&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;signal&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SIGTERM&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;#or signal.SIGKILL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#convert-the-parameter-of-an-api-get-request-to-a-valid-field&#34;&gt;Convert the parameter of an API get request to a valid field.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;For example if the argument has &lt;code&gt;/&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;urllib.parse&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;quote&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;quote&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;value/with/slashes&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Will return &lt;code&gt;value%2Fwith%2Fslashes&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-the-type-hints-of-an-object&#34;&gt;Get the type hints of an object.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;```python from typing import get_type_hints&lt;/p&gt; &lt;p&gt;Student(NamedTuple): name: Annotated[str, &#39;some marker&#39;]&lt;/p&gt; &lt;p&gt;get_type_hints(Student) == {&#39;name&#39;: str} get_type_hints(Student, include_extras=False) == {&#39;name&#39;: str} get_type_hints(Student, include_extras=True) == { &#39;name&#39;: Annotated[str, &#39;some marker&#39;] } ````&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#type-hints-of-a-python-module&#34;&gt;Type hints of a python module.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;types&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ModuleType&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ModuleType&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-all-the-classes-of-a-python-module&#34;&gt;Get all the classes of a python module.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;_load_classes_from_directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;classes&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file_name&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;listdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file_name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;endswith&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;.py&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file_name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;__init__.py&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;module_name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;splitext&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;module_path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;join&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

            &lt;span class=&#34;c1&#34;&gt;# Import the module dynamically&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;spec&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;spec_from_file_location&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;module_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;module_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;spec&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;loader&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;ValueError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                    &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Error loading the spec of &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;module_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; from &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;module_path&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
                &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;module&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;module_from_spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;loader&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exec_module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

            &lt;span class=&#34;c1&#34;&gt;# Retrieve all classes from the module&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;module_classes&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inspect&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getmembers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inspect&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isclass&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;classes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;extend&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;module_classes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#import-files-from-other-directories&#34;&gt;Import files from other directories.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Add the directory where you have your function to &lt;code&gt;sys.path&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;sys&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;**Put here the directory where you have the file with your function**&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;file&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;function&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#use-path-of-pathlib-write_text-in-append-mode&#34;&gt;Use Path of pathlib write_text in append mode.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It&#39;s not supported you need to &lt;code&gt;open&lt;/code&gt; it:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;my_path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;a&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;...&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#suppress-ann401-for-dynamically-typed-*args-and-**kwargs&#34;&gt;Suppress ANN401 for dynamically typed *args and **kwargs.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use &lt;code&gt;object&lt;/code&gt; instead:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;object&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kwargs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;object&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#one-liner-conditional&#34;&gt;One liner conditional.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To write an if-then-else statement in Python so that it fits on one line you can use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;fruit&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;Apple&#39;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;isApple&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fruit&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;Apple&#39;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-package-data-relative-path&#34;&gt;Get package data relative path.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you want to reference files from the foo/package1/resources folder you would want to use the &lt;strong&gt;file&lt;/strong&gt; variable of the module. Inside foo/package1/&lt;strong&gt;init&lt;/strong&gt;.py:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;resources_dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;join&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dirname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;vm&#34;&gt;__file__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;resources&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#compare-file-and-directories&#34;&gt;Compare file and directories.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The filecmp module defines functions to compare files and directories, with various optional time/correctness trade-offs. For comparing files, see also the difflib module.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;filecmp&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dircmp&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;print_diff_files&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dcmp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dcmp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;diff_files&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;diff_file &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%s&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; found in &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%s&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; and &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%s&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dcmp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;left&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dcmp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;right&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sub_dcmp&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dcmp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subdirs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;values&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;print_diff_files&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sub_dcmp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;dcmp&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dircmp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;dir1&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;dir2&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;print_diff_files&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dcmp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#send-a-linux-desktop-notification&#34;&gt;Send a linux desktop notification.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To show a Linux desktop notification from a Python script, you can use the &lt;code&gt;notify2&lt;/code&gt; library (although &lt;a href=&#34;https://pypi.org/project/notify2/&#34;&gt;it&#39;s last commit was done on 2017&lt;/a&gt;. This library provides an easy way to send desktop notifications on Linux.&lt;/p&gt; &lt;p&gt;Alternatively, you can use the &lt;code&gt;subprocess&lt;/code&gt; module to call the &lt;code&gt;notify-send&lt;/code&gt; command-line utility directly. This is a more straightforward method but requires &lt;code&gt;notify-send&lt;/code&gt; to be installed.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;subprocess&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;send_notification&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;urgency&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;normal&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Send a desktop notification using notify-send.&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;    Args:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        title (str): The title of the notification.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        message (str): The message body of the notification. Defaults to an empty string.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        urgency (str): The urgency level of the notification. Can be &#39;low&#39;, &#39;normal&#39;, or &#39;critical&#39;. Defaults to &#39;normal&#39;.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    &#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;notify-send&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;-u&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;urgency&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-the-error-string&#34;&gt;Get the error string.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;traceback&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;cause_error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# This will raise a ZeroDivisionError&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;cause_error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;Exception&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;# Capture the exception traceback as a string&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;error_message&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;join&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;traceback&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;format_exception&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;__traceback__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;An error occurred:&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;error_message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;goodconf&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/goodconf/&#34;&gt;Goodconf&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/goodconf/#initialize-the-config-with-a-default-value-if-the-file-doesn&#39;t-exist&#34;&gt;Initialize the config with a default value if the file doesn&#39;t exist.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Optional&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_config_file&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;store_dir&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;warning&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;The store directory doesn&#39;t exist. Creating it&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;makedirs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;store_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;config_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;warning&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;The yaml store file doesn&#39;t exist. Creating it&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;save&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;nb&#34;&gt;super&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; feat(goodconf#Config saving)&lt;/p&gt; &lt;p&gt;So far &lt;a href=&#34;https://github.com/lincolnloop/goodconf/issues/12&#34;&gt;&lt;code&gt;goodconf&lt;/code&gt; doesn&#39;t support saving the config&lt;/a&gt;. Until it&#39;s ready you can use the next snippet:&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;YamlStorage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GoodConf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Adapter to store and load information from a yaml file.&#34;&#34;&#34;&lt;/span&gt;

    &lt;span class=&#34;nd&#34;&gt;@property&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;config_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Return the path to the config file.&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_config_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;nd&#34;&gt;@property&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;store_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Return the path to the store directory.&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;config_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parent&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;reload&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Reload the contents of the authentication store.&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;config_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Optional&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Load a configuration file.&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;store_dir&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/data.yaml&#34;&lt;/span&gt;
        &lt;span class=&#34;nb&#34;&gt;super&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;config_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;save&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Save the contents of the authentication store.&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;config_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;w+&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;encoding&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;utf-8&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file_cursor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;yaml&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;YAML&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;yaml&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;default_flow_style&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;yaml&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dump&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file_cursor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; feat(google_chrome#Open a specific profile): Open a specific profile&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;google-chrome&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--profile-directory&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Profile Name&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where &lt;code&gt;Profile Name&lt;/code&gt; is one of the profiles listed under &lt;code&gt;ls ~/.config/chromium | grep -i profile&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;inotify&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/python_inotify/&#34;&gt;Inotify&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce python_inotify.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://pypi.org/project/inotify/&#34;&gt;inotify&lt;/a&gt; is a python library that acts as a bridge to the &lt;code&gt;inotify&lt;/code&gt; linux kernel which allows you to register one or more directories for watching, and to simply block and wait for notification events. This is obviously far more efficient than polling one or more directories to determine if anything has changed.&lt;/p&gt; &lt;p&gt;Installation:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;inotify
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Basic example using a loop:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;inotify.adapters&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;_main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inotify&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;adapters&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Inotify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_watch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;/tmp&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;/tmp/test_file&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;w&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;pass&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;event&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;event_gen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yield_nones&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;type_names&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;

        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;PATH=[&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;] FILENAME=[&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;] EVENT_TYPES=&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
              &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;type_names&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;__main__&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;_main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Output:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;PATH=[/tmp] FILENAME=[test_file] EVENT_TYPES=[&#39;IN_MODIFY&#39;]
PATH=[/tmp] FILENAME=[test_file] EVENT_TYPES=[&#39;IN_OPEN&#39;]
PATH=[/tmp] FILENAME=[test_file] EVENT_TYPES=[&#39;IN_CLOSE_WRITE&#39;]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Basic example without a loop:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;inotify.adapters&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;_main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inotify&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;adapters&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Inotify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_watch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;/tmp&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;/tmp/test_file&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;w&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;pass&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;events&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;event_gen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yield_nones&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;timeout_s&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;events&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;events&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;events&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;__main__&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;_main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The wait will be done in the &lt;code&gt;list(events)&lt;/code&gt; line&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Deprecate inotify.&lt;/p&gt; &lt;p&gt;DEPRECATED: As of 2024-11-15 it&#39;s been 4 years since the last commit. &lt;a href=&#34;https://lyz-code.github.io/blue-book/watchdog_python/&#34;&gt;watchdog&lt;/a&gt; has 6.6k stars and last commit was done 2 days ago.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;watchdog&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/watchdog_python/&#34;&gt;watchdog&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce watchdog.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/gorakhargosh/watchdog?tab=readme-ov-file&#34;&gt;watchdog&lt;/a&gt; is a Python library and shell utilities to monitor filesystem events.&lt;/p&gt; &lt;p&gt;Cons:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The &lt;a href=&#34;https://python-watchdog.readthedocs.io/en/stable/api.html&#34;&gt;docs&lt;/a&gt; suck.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;watchdog
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;A simple program that uses watchdog to monitor directories specified as command-line arguments and logs events generated:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;time&lt;/span&gt;

&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;watchdog.events&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FileSystemEvent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FileSystemEventHandler&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;watchdog.observers&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Observer&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;MyEventHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FileSystemEventHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;on_any_event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FileSystemEvent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;event_handler&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;MyEventHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;observer&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Observer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;observer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;schedule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;event_handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;.&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;recursive&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;observer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sleep&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;finally&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;observer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;observer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;join&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt; - &lt;a href=&#34;https://github.com/gorakhargosh/watchdog?tab=readme-ov-file&#34;&gt;Source&lt;/a&gt; - &lt;a href=&#34;https://python-watchdog.readthedocs.io&#34;&gt;Docs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pydantic&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pydantic/&#34;&gt;Pydantic&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Nicely show validation errors.&lt;/p&gt; &lt;p&gt;A nice way of showing it is to capture the error and print it yourself:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;model&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Model&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;state&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;state&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ValidationError&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Error building model with state &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;state&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pydantic/#load-a-pydantic-model-from-json&#34;&gt;Load a pydantic model from json.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can use the &lt;a href=&#34;https://docs.pydantic.dev/latest/api/base_model/#pydantic.main.BaseModel.model_validate_json&#34;&gt;&lt;code&gt;model_validate_json&lt;/code&gt;&lt;/a&gt; method that will validate and return an object with the loaded data.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;datetime&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;date&lt;/span&gt;

&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pydantic&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;BaseModel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ConfigDict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ValidationError&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BaseModel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;model_config&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ConfigDict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;strict&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;when&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;date&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;where&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;tuple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;json_data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;{&#34;when&#34;: &#34;1987-01-28&#34;, &#34;where&#34;: [51, -1]}&#39;&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Event&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;model_validate_json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;json_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;Event&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;model_validate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;when&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;1987-01-28&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;where&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;51&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]})&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ValidationError&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    2 validation errors for Event&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    when&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;      Input should be a valid date [type=date_type, input_value=&#39;1987-01-28&#39;, input_type=str]&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    where&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;      Input should be a valid tuple [type=tuple_type, input_value=[51, -1], input_type=list]&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    &#34;&#34;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Create part of the attributes in the initialization stage.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Sqlite&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BaseModel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;model_config&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ConfigDict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;arbitrary_types_allowed&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sqlite3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Cursor&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__init__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kwargs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;conn&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sqlite3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;connect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kwargs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;path&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;kwargs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;db&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;conn&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cursor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;nb&#34;&gt;super&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;fm&#34;&gt;__init__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kwargs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;psycopg2&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/psycopg2/&#34;&gt;psycopg2&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce psycopg2.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Install the dependencies:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libpq-dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;python3-dev
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then install the package&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;psycopg2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;questionary&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/questionary/&#34;&gt;questionary&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/questionary/#unit-testing&#34;&gt;Unit testing questionary code.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Testing &lt;code&gt;questionary&lt;/code&gt; code can be challenging because it involves interactive prompts that expect user input. However, there are ways to automate the testing process. You can use libraries like &lt;code&gt;pexpect&lt;/code&gt;, &lt;code&gt;pytest&lt;/code&gt;, and &lt;code&gt;pytest-mock&lt;/code&gt; to simulate user input and test the behavior of your code.&lt;/p&gt; &lt;p&gt;Here’s how you can approach testing &lt;code&gt;questionary&lt;/code&gt; code using &lt;code&gt;pytest-mock&lt;/code&gt; to mock &lt;code&gt;questionary&lt;/code&gt; functions&lt;/p&gt; &lt;p&gt;You can mock &lt;code&gt;questionary&lt;/code&gt; functions like &lt;code&gt;questionary.select().ask()&lt;/code&gt; to simulate user choices without actual user interaction.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Testing a single &lt;code&gt;questionary.text&lt;/code&gt; prompt&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Let&#39;s assume you have a function that asks the user for their name:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;questionary&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;ask_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;questionary&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;What&#39;s your name?&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ask&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can test this function by mocking the &lt;code&gt;questionary.text&lt;/code&gt; prompt to simulate the user&#39;s input.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pytest&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;your_module&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ask_name&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;test_ask_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mocker&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;# Mock the text function to simulate user input&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;mock_text&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mocker&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;patch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;questionary.text&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;# Define the response for the prompt&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;mock_text&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;return_value&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ask&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;return_value&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Alice&#34;&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ask_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Alice&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Test a function that has many questions&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Here’s an example of how to test a function that contains two &lt;code&gt;questionary.text&lt;/code&gt; prompts using &lt;code&gt;pytest-mock&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Let&#39;s assume you have a function that asks for the first and last names of a user:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;questionary&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;ask_full_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;first_name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;questionary&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;What&#39;s your first name?&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ask&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;last_name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;questionary&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;What&#39;s your last name?&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ask&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;first_name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;first_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;last_name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;last_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can mock both &lt;code&gt;questionary.text&lt;/code&gt; calls to simulate user input for both the first and last names:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pytest&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;your_module&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ask_full_name&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;test_ask_full_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mocker&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;# Mock the text function for the first name prompt&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;mock_text_first&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mocker&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;patch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;questionary.text&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;# Define the response for the first name prompt&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;mock_text_first&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;side_effect&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Alice&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Smith&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ask_full_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;first_name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Alice&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;last_name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Smith&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;rich&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/rich/&#34;&gt;rich&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Adding a footer to a table.&lt;/p&gt; &lt;p&gt;Adding a footer is not easy task. &lt;a href=&#34;https://github.com/Textualize/rich/discussions/2135&#34;&gt;This answer&lt;/a&gt; doesn&#39;t work anymore as &lt;code&gt;table&lt;/code&gt; doesn&#39;t have the &lt;code&gt;add_footer&lt;/code&gt;. You need to create the footer in the &lt;code&gt;add_column&lt;/code&gt; so you need to have the data that needs to go to the footer before building the rows.&lt;/p&gt; &lt;p&gt;You would do something like:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;table&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Table&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Star Wars Movies&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;show_footer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;table&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_column&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Title&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;style&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;magenta&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;footer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;2342&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;coding-tools&#34;&gt;Coding tools&lt;/h3&gt; &lt;h4 id=&#34;singer&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_foldings/&#34;&gt;Singer&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce neotree.&lt;/p&gt; &lt;p&gt;General keymaps:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;&amp;lt;cr&amp;gt;&lt;/code&gt;: Open the file in the current buffer&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;s&amp;gt;&lt;/code&gt;: Open in a vertical split&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;S&amp;gt;&lt;/code&gt;: Open in an horizontal split&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;bs&amp;gt;&lt;/code&gt;: Navigate one directory up (even if it&#39;s the root of the &lt;code&gt;cwd&lt;/code&gt;)&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;File and directory management:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;a&lt;/code&gt;: Create a new file or directory. Add a &lt;code&gt;/&lt;/code&gt; to the end of the name to make a directory.&lt;/li&gt; &lt;li&gt;&lt;code&gt;d&lt;/code&gt;: Delete the selected file or directory&lt;/li&gt; &lt;li&gt;&lt;code&gt;r&lt;/code&gt;: Rename the selected file or directory&lt;/li&gt; &lt;li&gt;&lt;code&gt;y&lt;/code&gt;: Mark file to be copied (supports visual selection)&lt;/li&gt; &lt;li&gt;&lt;code&gt;x&lt;/code&gt;: Mark file to be cut (supports visual selection)&lt;/li&gt; &lt;li&gt;&lt;code&gt;m&lt;/code&gt;: Move the selected file or directory&lt;/li&gt; &lt;li&gt;&lt;code&gt;c&lt;/code&gt;: Copy the selected file or directory&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;References:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/nvim-neo-tree/neo-tree.nvim/blob/main/doc/neo-tree.txt&#34;&gt;Docs&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/nvim-neo-tree/neo-tree.nvim/wiki&#34;&gt;Wiki&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/nvim-neo-tree/neo-tree.nvim/wiki/Recipes&#34;&gt;Wiki Recipes&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/neotree/#show-hidden-files&#34;&gt;Show hidden files.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;s2&#34;&gt;&#34;nvim-neo-tree/neo-tree.nvim&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;opts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;filesystem&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;filtered_items&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;visible&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;show_hidden_count&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;hide_dotfiles&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;hide_gitignored&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;hide_by_name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;s1&#34;&gt;&#39;.git&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;never_show&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/neotree/#autoclose-on-open-file&#34;&gt;Autoclose on open file.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This example uses the file_open event to close the Neo-tree window when a file is opened. This applies to all windows and all sources at once.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;neo-tree&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;event_handlers&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;

    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;event&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;file_opened&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;handler&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;-- auto close&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;-- vimc.cmd(&#34;Neotree close&#34;)&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;-- OR&lt;/span&gt;
        &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;neo-tree.command&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;execute&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;action&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;close&#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
      &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;

  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/neotree/#configuring-vim-folds&#34;&gt;Configuring vim folds.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Copy the code under &lt;a href=&#34;https://github.com/nvim-neo-tree/neo-tree.nvim/wiki/Recipes#emulating-vims-fold-commands&#34;&gt;implementation&lt;/a&gt; in your config file.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/neotree/#can&#39;t-copy-file/directory-to-itself&#34;&gt;Can&#39;t copy file/directory to itself.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you want to copy a directory you need to assume that the prompt is done from within the directory. So if you want to copy it to a new name at the same level you need to use &lt;code&gt;../new-name&lt;/code&gt; instead of &lt;code&gt;new-name&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce the vim foldings workflow.&lt;/p&gt; &lt;p&gt;ne way to easily work with folds is by using the &lt;a href=&#34;https://github.com/jghauser/fold-cycle.nvim?tab=readme-ov-file&#34;&gt;fold-cycle&lt;/a&gt; plugin to be able to press &lt;code&gt;&amp;lt;tab&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;enter&amp;gt;&lt;/code&gt; to toggle a fold.&lt;/p&gt; &lt;p&gt;If you&#39;re using &lt;a href=&#34;https://lyz-code.github.io/blue-book/lazyvim/&#34;&gt;lazyvim&lt;/a&gt; you can use the next configuration:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;jghauser/fold-cycle.nvim&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
      &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;fold-cycle&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;tab&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;fold-cycle&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Fold-cycle: open folds&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;cr&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;fold-cycle&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Fold-cycle: open folds&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;s-tab&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;fold-cycle&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Fold-cycle: close folds&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;zC&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;fold-cycle&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;close_all&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;remap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Fold-cycle: close all folds&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce singer.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.singer.io/&#34;&gt;Singer&lt;/a&gt; is an open-source standard for writing scripts that move data.&lt;/p&gt; &lt;p&gt;It describes how data extraction scripts—called “taps” —and data loading scripts—called “targets”— should communicate, allowing them to be used in any combination to move data from any source to any destination. Send data between databases, web APIs, files, queues, and just about anything else you can think of.&lt;/p&gt; &lt;p&gt;It has many &#34;taps&#34; and &#34;targets&#34; that can help you interact with third party tools without needing to write the code.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt; - &lt;a href=&#34;https://www.singer.io/&#34;&gt;Home&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/#&amp;lt;c-i&amp;gt;-is-not-well-mapped&#34;&gt;&lt;c-i&gt; is not well mapped.&lt;/c-i&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It&#39;s because &lt;code&gt;&amp;lt;c-i&amp;gt;&lt;/code&gt; is a synonym of &lt;code&gt;&amp;lt;TAB&amp;gt;&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;coding-with-ai&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_movement/&#34;&gt;Coding with AI&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce LazyVim.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/LazyVim/LazyVim&#34;&gt;Source&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lazyvim.github.io/&#34;&gt;Docs&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lazyvim.github.io/&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/lazyvim/#adding-plugins-configuration&#34;&gt;Adding plugins configuration.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Configuring LazyVim plugins is exactly the same as using &lt;code&gt;lazy.nvim&lt;/code&gt; to build a config from scratch.&lt;/p&gt; &lt;p&gt;For the full plugin spec documentation please check the &lt;a href=&#34;https://github.com/folke/lazy.nvim&#34;&gt;lazy.nvim readme&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;LazyVim comes with a list of preconfigured plugins, check them &lt;a href=&#34;https://www.lazyvim.org/configuration/plugins&#34;&gt;here&lt;/a&gt; before diving on your own.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/lazyvim/#adding-a-plugin&#34;&gt;Adding a plugin.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Adding a plugin is as simple as adding the plugin spec to one of the files under `lua/plugins/*.lua``. You can create as many files there as you want.&lt;/p&gt; &lt;p&gt;You can structure your &lt;code&gt;lua/plugins`` folder with a file per plugin, or a separate file containing all the plugin specs for some functionality. For example:&lt;/code&gt;lua/plugins/lsp.lua`&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;-- add symbols-outline&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;simrat39/symbols-outline.nvim&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;SymbolsOutline&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;leader&amp;gt;cs&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;cmd&amp;gt;SymbolsOutline&amp;lt;cr&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Symbols Outline&#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;opts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;c1&#34;&gt;-- add your options that should be passed to the setup() function here&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;position&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;right&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Customizing plugin specs. Defaults merging rules:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;cmd: the list of commands will be extended with your custom commands&lt;/li&gt; &lt;li&gt;event: the list of events will be extended with your custom events&lt;/li&gt; &lt;li&gt;ft: the list of filetypes will be extended with your custom filetypes&lt;/li&gt; &lt;li&gt;keys: the list of keymaps will be extended with your custom keymaps&lt;/li&gt; &lt;li&gt;opts: your custom opts will be merged with the default opts&lt;/li&gt; &lt;li&gt;dependencies: the list of dependencies will be extended with your custom dependencies&lt;/li&gt; &lt;li&gt;any other property will override the defaults&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;For ft, event, keys, cmd and opts you can instead also specify a values function that can make changes to the default values, or return new values to be used instead.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;c1&#34;&gt;-- change trouble config&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;s2&#34;&gt;&#34;folke/trouble.nvim&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;-- opts will be merged with the parent spec&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;opts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;use_diagnostic_signs&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;-- add cmp-emoji&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;s2&#34;&gt;&#34;hrsh7th/nvim-cmp&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;dependencies&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;hrsh7th/cmp-emoji&#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;---@param opts cmp.ConfigSchema&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;opts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;opts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;table.insert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;opts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;emoji&#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
  &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Defining the plugin keymaps:&lt;/p&gt; &lt;p&gt;Adding &lt;code&gt;keys=&lt;/code&gt; follows the rules as explained above. You don&#39;t have to specify a mode for &lt;code&gt;normal&lt;/code&gt; mode keymaps.&lt;/p&gt; &lt;p&gt;You can also disable a default keymap by setting it to &lt;code&gt;false&lt;/code&gt;. To override a keymap, simply add one with the same &lt;code&gt;lhs&lt;/code&gt; and a new &lt;code&gt;rhs&lt;/code&gt;. For example &lt;code&gt;lua/plugins/telescope.lua&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;s2&#34;&gt;&#34;nvim-telescope/telescope.nvim&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;-- disable the keymap to grep files&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;leader&amp;gt;/&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;-- change a keymap&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;leader&amp;gt;ff&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;cmd&amp;gt;Telescope find_files&amp;lt;cr&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Find Files&#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;-- add a keymap to browse plugin files&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;leader&amp;gt;fp&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;telescope.builtin&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;find_files&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cwd&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;lazy.core.config&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;root&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Find Plugin File&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Make sure to use the exact same mode as the keymap you want to disable.&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;s2&#34;&gt;&#34;folke/flash.nvim&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;-- disable the default flash keymap&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;s&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mode&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;x&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;o&#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; You can also return a whole new set of keymaps to be used instead. Or return &lt;code&gt;{}&lt;/code&gt; to disable all keymaps for a plugin.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;s2&#34;&gt;&#34;nvim-telescope/telescope.nvim&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;-- replace all Telescope keymaps with only one mapping&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;leader&amp;gt;ff&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;cmd&amp;gt;Telescope find_files&amp;lt;cr&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Find Files&#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
  &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/lazyvim/#auto-update-plugins&#34;&gt;Auto update plugins.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Add this to &lt;code&gt;~/.config/nvim/lua/config/autocomds.lua&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;augroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_create_augroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;lazyvim_&#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;clear&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_create_autocmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;VimEnter&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;group&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;augroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;autoupdate&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;callback&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;lazy.status&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;has_updates&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
      &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;lazy&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;update&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;show&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
    &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
  &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce vim keymaps.&lt;/p&gt; &lt;p&gt;LazyVim comes with some sane default keybindings, you can see them &lt;a href=&#34;https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/keymaps.lua&#34;&gt;here&lt;/a&gt;. You don&#39;t need to remember them all, it also comes with &lt;a href=&#34;https://github.com/folke/which-key.nvim&#34;&gt;which-key&lt;/a&gt; to help you remember your keymaps. Just press any key like &lt;space&gt; and you&#39;ll see a popup with all possible keymaps starting with &lt;space&gt;.&lt;/space&gt;&lt;/space&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;default &lt;code&gt;&amp;lt;leader&amp;gt;&lt;/code&gt; is &lt;code&gt;&amp;lt;space&amp;gt;&lt;/code&gt;&lt;/li&gt; &lt;li&gt;default &lt;code&gt;&amp;lt;localleader&amp;gt;&lt;/code&gt; is &lt;code&gt;\&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;General editor bindings:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Save file: &lt;code&gt;&amp;lt;C-s&amp;gt;&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Quit all: &lt;code&gt;&amp;lt;leader&amp;gt;qq&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Open a floating terminal: &lt;code&gt;&amp;lt;C-/&amp;gt;&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Movement keybindings:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Split the windows:&lt;/li&gt; &lt;li&gt;Vertically: &lt;code&gt;&amp;lt;C-|&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Horizontally: &lt;code&gt;&amp;lt;C--&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Delete window: &lt;code&gt;&amp;lt;leader&amp;gt;wd&lt;/code&gt;&lt;/li&gt; &lt;li&gt;To move around the windows you can use: &lt;c-h&gt;, &lt;c-j&gt;, &lt;c-k&gt;, &lt;c-l&gt;.&lt;/c-l&gt;&lt;/c-k&gt;&lt;/c-j&gt;&lt;/c-h&gt;&lt;/li&gt; &lt;li&gt;To resize the windows use: &lt;c-up&gt;, &lt;c-down&gt;, &lt;c-left&gt;, &lt;c-right&gt;&lt;/c-right&gt;&lt;/c-left&gt;&lt;/c-down&gt;&lt;/c-up&gt;&lt;/li&gt; &lt;li&gt;To move between buffers:&lt;/li&gt; &lt;li&gt;Next and previous with &lt;s-h&gt;, &lt;s-l&gt;&lt;/s-l&gt;&lt;/s-h&gt;&lt;/li&gt; &lt;li&gt;Switch to the previously opened buffer: &lt;code&gt;&amp;lt;leader&amp;gt;bb&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Coding keybindings:&lt;/p&gt; &lt;p&gt;Diagnostics:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;&amp;lt;leader&amp;gt;cd&amp;gt;&lt;/code&gt;: Shows you the diagnostics message of the current line in a floating window&lt;/li&gt; &lt;li&gt;&lt;code&gt;]d&lt;/code&gt; and &lt;code&gt;[d&lt;/code&gt;: iterates over all diagnostics&lt;/li&gt; &lt;li&gt;&lt;code&gt;]e&lt;/code&gt; and &lt;code&gt;[e&lt;/code&gt;: iterates over all error diagnostics&lt;/li&gt; &lt;li&gt;&lt;code&gt;]w&lt;/code&gt; and &lt;code&gt;[w&lt;/code&gt;: iterates over all warning diagnostics&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_keymaps/#setting-keymaps-in-lua&#34;&gt;Setting keymaps in lua.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you need to set keymaps in lua you can use &lt;code&gt;vim.keymap.set&lt;/code&gt;. For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;space&amp;gt;w&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;cmd&amp;gt;write&amp;lt;cr&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;Save&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;After executing this, the sequence &lt;code&gt;Space + w&lt;/code&gt; will call the &lt;code&gt;write&lt;/code&gt; command. Basically, we can save changes made to a file with &lt;code&gt;Space + w&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Let&#39;s dive into what does the &lt;code&gt;vim.keymap.set&lt;/code&gt; parameters mean.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lhs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rhs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;opts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;{mode}&lt;/code&gt;: mode where the keybinding should execute. It can be a list of modes. We need to speify the mode&#39;s short name. Here are some of the most common.&lt;/li&gt; &lt;li&gt;&lt;code&gt;n&lt;/code&gt;: Normal mode.&lt;/li&gt; &lt;li&gt;&lt;code&gt;i&lt;/code&gt;: Insert mode.&lt;/li&gt; &lt;li&gt;&lt;code&gt;x&lt;/code&gt;: Visual mode.&lt;/li&gt; &lt;li&gt;&lt;code&gt;s&lt;/code&gt;: Selection mode.&lt;/li&gt; &lt;li&gt;&lt;code&gt;v&lt;/code&gt;: Visual + Selection.&lt;/li&gt; &lt;li&gt;&lt;code&gt;t&lt;/code&gt;: Terminal mode.&lt;/li&gt; &lt;li&gt;&lt;code&gt;o&lt;/code&gt;: Operator-pending.&lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;code&gt;&#39;&#39;&lt;/code&gt;: Yes, an empty string. Is the equivalent of &lt;code&gt;n + v + o&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;code&gt;{lhs}&lt;/code&gt;: is the key we want to bind.&lt;/p&gt; &lt;/li&gt; &lt;li&gt;&lt;code&gt;{rhs}&lt;/code&gt; is the action we want to execute. It can be a string with a command or an expression. You can also provide a lua function.&lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;code&gt;{opts}&lt;/code&gt; this must be a lua table. If you don&#39;t know what is a &#34;lua table&#34; just think is a way of storing several values in one place. Anyway, it can have these properties.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;code&gt;desc&lt;/code&gt;: A string that describes what the keybinding does. You can write anything you want.&lt;/p&gt; &lt;/li&gt; &lt;li&gt;&lt;code&gt;remap&lt;/code&gt;: A boolean that determines if our keybinding can be recursive. The default value is &lt;code&gt;false&lt;/code&gt;. Recursive keybindings can cause some conflicts if used incorrectly. Don&#39;t enable it unless you know what you&#39;re doing.&lt;/li&gt; &lt;li&gt;&lt;code&gt;buffer&lt;/code&gt;: It can be a boolean or a number. If we assign the boolean &lt;code&gt;true&lt;/code&gt; it means the keybinding will only be effective in the current file. If we assign a number, it needs to be the &#34;id&#34; of an open buffer.&lt;/li&gt; &lt;li&gt;&lt;code&gt;silent&lt;/code&gt;: A boolean. Determines whether or not the keybindings can show a message. The default value is &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;&lt;code&gt;expr&lt;/code&gt;: A boolean. If enabled it gives the chance to use vimscript or lua to calculate the value of &lt;code&gt;{rhs}&lt;/code&gt;. The default value is &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_keymaps/#the-leader-key&#34;&gt;The leader key.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;When creating keybindings we can use the special sequence &lt;code&gt;&amp;lt;leader&amp;gt;&lt;/code&gt; in the &lt;code&gt;{lhs}&lt;/code&gt; parameter, it&#39;ll take the value of the global variable &lt;code&gt;mapleader&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;So &lt;code&gt;mapleader&lt;/code&gt; is a global variable in vimscript that can be string. For example.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mapleader&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39; &#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;After defining it we can use it as a prefix in our keybindings.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;w&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;cmd&amp;gt;write&amp;lt;cr&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This will make &lt;code&gt;&amp;lt;space key&amp;gt;&lt;/code&gt; + &lt;code&gt;w&lt;/code&gt; save the current file.&lt;/p&gt; &lt;p&gt;There are different opinions on what key to use as the &lt;code&gt;&amp;lt;leader&amp;gt;&lt;/code&gt; key. The &lt;code&gt;&amp;lt;space&amp;gt;&lt;/code&gt; is the most comfortable as it&#39;s always close to your thumbs, and it works well with both hands. Nevertheless, you can only use it in normal mode, because in insert &lt;code&gt;&amp;lt;space&amp;gt;&amp;lt;whatever&amp;gt;&lt;/code&gt; will be triggered as you write. An alternative is to use &lt;code&gt;;&lt;/code&gt; which is also comfortable (if you use the english key distribution) and you can use it in insert mode.&lt;/p&gt; &lt;p&gt;If you &lt;a href=&#34;https://stackoverflow.com/questions/30467660/can-we-define-more-than-one-leader-key-in-vimrc&#34;&gt;want to define more than one leader key&lt;/a&gt; you can either:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Change the &lt;code&gt;mapleader&lt;/code&gt; many times in your file: As the value of &lt;code&gt;mapleader&lt;/code&gt; is used at the moment the mapping is defined, you can indeed change that while plugins are loading. For that, you have to explicitly &lt;code&gt;:runtime&lt;/code&gt; the plugins in your &lt;code&gt;~/.vimrc&lt;/code&gt; (and count on the canonical include guard to prevent redefinition later):&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;let&lt;/span&gt; mapleader &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;,&#39;&lt;/span&gt;
runtime&lt;span class=&#34;p&#34;&gt;!&lt;/span&gt; plugin/NERD_commenter.&lt;span class=&#34;k&#34;&gt;vim&lt;/span&gt;
runtime&lt;span class=&#34;p&#34;&gt;!&lt;/span&gt; ...
&lt;span class=&#34;k&#34;&gt;let&lt;/span&gt; mapleader &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;\&#39;&lt;/span&gt;
runime&lt;span class=&#34;p&#34;&gt;!&lt;/span&gt; plugin/mark.&lt;span class=&#34;k&#34;&gt;vim&lt;/span&gt;
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; * Use the keys directly instead of using &lt;code&gt;&amp;lt;leader&amp;gt;&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;c&#34;&gt;&#34; editing mappings&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;nnoremap&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;something&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;nnoremap&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;k&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;something &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;nnoremap&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;d&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;and something &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&#34;c&#34;&gt;&#34; window management mappings&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;nnoremap&lt;/span&gt; gw &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;something&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;nnoremap&lt;/span&gt; gb &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;something &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Defining &lt;code&gt;mapleader&lt;/code&gt; and/or using &lt;code&gt;&amp;lt;leader&amp;gt;&lt;/code&gt; may be useful if you change your mind often on what key to use a leader but it won&#39;t be of any use if your mappings are stable.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Configure vim from scratch.&lt;/p&gt; &lt;p&gt;Neovim configuration is a &lt;strong&gt;complex&lt;/strong&gt; thing to do, both to start and to maintain. The configurations are endless, the plugins are too. Be ready to spend a lot of energy on it and to get lost reading a lot.&lt;/p&gt; &lt;p&gt;If I&#39;m scaring you, you are right to be scared! xD. Once you manage to get it configured to your liking you&#39;ll think that in the end it doesn&#39;t even matter spending all that time. However if you&#39;re searching for something that is plug and play try &lt;a href=&#34;https://lyz-code.github.io/blue-book/vscodium/&#34;&gt;vscodium&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;To make things worse, the configuration &lt;a href=&#34;#configuration-done-in-Lua&#34;&gt;is done in lua&lt;/a&gt;, so you may need a &lt;a href=&#34;https://lyz-code.github.io/blue-book/lua/&#34;&gt;small refreshment&lt;/a&gt; to understand what are you doing.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_config/#vim-distributions&#34;&gt;Vim distributions.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;One way to make vim&#39;s configuration more bearable is to use vim distributions. These are projects that maintain configurations with sane defaults and that work with the whole ecosystem of plugins.&lt;/p&gt; &lt;p&gt;Using them is the best way to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Have something usable fast&lt;/li&gt; &lt;li&gt;Minimize the maintenance efforts as others are doing it for you (plugin changes, breaking changes, ..)&lt;/li&gt; &lt;li&gt;Keep updated with the neovim ecosystem, as you can see what is the community adding to the default config.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;However, there are so many good Neovim configuration distributions that it becomes difficult for a Neovim user to decide which distribution to use and how to tailor it for their use case.&lt;/p&gt; &lt;p&gt;By far, the top 5 Neovim configuration distributions are &lt;a href=&#34;https://github.com/AstroNvim/AstroNvim&#34;&gt;AstroNvim&lt;/a&gt;, &lt;a href=&#34;https://github.com/nvim-lua/kickstart.nvim&#34;&gt;kickstart&lt;/a&gt;, &lt;a href=&#34;https://github.com/LazyVim/LazyVim&#34;&gt;LazyVim&lt;/a&gt;, &lt;a href=&#34;https://github.com/LunarVim/LunarVim&#34;&gt;LunarVim&lt;/a&gt;, and &lt;a href=&#34;https://github.com/NvChad/NvChad&#34;&gt;NvChad&lt;/a&gt;. That is not to say these are the “best” configuration distributions, simply that they are the most popular.&lt;/p&gt; &lt;p&gt;Each of these configuration distributions has value. They all provide excellent starting points for crafting your own custom configuration, they are all extensible and fairly easy to learn, and they all provide an out-of-the-box setup that can be used effectively without modification.&lt;/p&gt; &lt;p&gt;Distinguishing features of the top Neovim configuration distributions are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;AstroNvim:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;An excellent community repository&lt;/li&gt; &lt;li&gt;Fully featured out-of-the-box&lt;/li&gt; &lt;li&gt;Good documentation&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;kickstart&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Minimal out-of-the-box setup&lt;/li&gt; &lt;li&gt;Easy to extend and widely used as a starting point&lt;/li&gt; &lt;li&gt;A good choice if your goal is hand-crafting your own config&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;LazyVim&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Very well maintained by the author of lazy.nvim&lt;/li&gt; &lt;li&gt;Nice architecture, it’s a plugin with which you can import preconfigured plugins&lt;/li&gt; &lt;li&gt;Good documentation&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;LunarVim&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Well maintained and mature&lt;/li&gt; &lt;li&gt;Custom installation processs installs LunarVim in an isolated location&lt;/li&gt; &lt;li&gt;Been around a while, large community, widespread presence on the web&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;NvChad&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Really great base46 plugin enables easy theme/colorscheme management&lt;/li&gt; &lt;li&gt;Includes an impressive mappings cheatsheet&lt;/li&gt; &lt;li&gt;ui plugin and nvim-colorizer&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Personally I tried LunarVim and finally ended up with LazyVim because:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;It&#39;s more popular&lt;/li&gt; &lt;li&gt;I like the file structure&lt;/li&gt; &lt;li&gt;It&#39;s being maintained by &lt;a href=&#34;https://github.com/folke&#34;&gt;folke&lt;/a&gt; one of the best developers of neovim plugins.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_config/#starting-your-configuration-with-lazyvim&#34;&gt;Starting your configuration with LazyVim.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.lazyvim.org/&#34;&gt;Installing the requirements&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;LazyVim needs the next tools to be able to work:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Neovim &amp;gt;= 0.9.0 (needs to be built with LuaJIT). Follow &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/#installation&#34;&gt;these instructions&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Git &amp;gt;= 2.19.0 (for partial clones support). &lt;code&gt;sudo apt-get install git&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;a &lt;a href=&#34;https://www.nerdfonts.com/&#34;&gt;Nerd Font(v3.0 or greater)&lt;/a&gt; (optional, but strongly suggested as they rae needed to display some icons). Follow &lt;a href=&#34;https://lyz-code.github.io/blue-book/kitty/#fonts&#34;&gt;these instructions if you&#39;re using kitty&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;lazygit (optional and I didn&#39;t like it)&lt;/li&gt; &lt;li&gt;a C compiler for nvim-treesitter. &lt;code&gt;apt-get install gcc&lt;/code&gt;&lt;/li&gt; &lt;li&gt;for telescope.nvim (optional)&lt;/li&gt; &lt;li&gt;live grep: &lt;code&gt;ripgrep&lt;/code&gt;&lt;/li&gt; &lt;li&gt;find files: &lt;code&gt;fd&lt;/code&gt;&lt;/li&gt; &lt;li&gt;a terminal that support true color and undercurl:&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/kitty/&#34;&gt;kitty (Linux &amp;amp; Macos)&lt;/a&gt;&lt;/li&gt; &lt;li&gt;wezterm (Linux, Macos &amp;amp; Windows)&lt;/li&gt; &lt;li&gt;alacritty (Linux, Macos &amp;amp; Windows)&lt;/li&gt; &lt;li&gt;iterm2 (Macos)&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;a href=&#34;https://www.lazyvim.org/installation&#34;&gt;Install the starter&lt;/a&gt;:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Make a backup of your current Neovim files: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;c1&#34;&gt;# required&lt;/span&gt;
mv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;~/.config/nvim&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;,.old&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;# optional but recommended&lt;/span&gt;
mv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;~/.local/share/nvim&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;,.old&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
mv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;~/.local/state/nvim&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;,.old&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
mv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;~/.cache/nvim&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;,.old&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;Clone the starter&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;clone&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://github.com/LazyVim/starter&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;~/.config/nvim
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Remove the &lt;code&gt;.git&lt;/code&gt; folder, so you can add it to your own repo later&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;rm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-rf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;~/.config/nvim/.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Start Neovim!&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;nvim
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; - It is recommended to run &lt;code&gt;:LazyHealth&lt;/code&gt; after installation. This will load all plugins and check if everything is working correctly.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;a href=&#34;https://www.lazyvim.org/configuration&#34;&gt;Understanding the file structure&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;The files under &lt;code&gt;config&lt;/code&gt; will be automatically loaded at the appropriate time, so you don&#39;t need to require those files manually.&lt;/p&gt; &lt;p&gt;You can add your custom plugin specs under &lt;code&gt;lua/plugins/&lt;/code&gt;. All files there will be automatically loaded by lazy.nvim.&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;~/.config/nvim
├── lua
│   ├── config
│   │   ├── autocmds.lua
│   │   ├── keymaps.lua
│   │   ├── lazy.lua
│   │   └── options.lua
│   └── plugins
│       ├── spec1.lua
│       ├── **
│       └── spec2.lua
└── init.toml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; The files &lt;code&gt;autocmds.lua&lt;/code&gt;, &lt;code&gt;keymaps.lua&lt;/code&gt;, &lt;code&gt;lazy.lua&lt;/code&gt; and &lt;code&gt;options.lua&lt;/code&gt; under &lt;code&gt;lua/config&lt;/code&gt; will be automatically loaded at the appropriate time, so you don&#39;t need to require those files manually. LazyVim comes with a set of default config files that will be loaded before your own.&lt;/p&gt; &lt;p&gt;You can continue your config by &lt;a href=&#34;https://lyz-code.github.io/blue-book/lazyvim/&#34;&gt;adding plugins&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce the vim movement workflow.&lt;/p&gt; &lt;p&gt;Moving around vim can be done in many ways, which an lead to being lost on how to do it well.&lt;/p&gt; &lt;p&gt;LazyVim has &lt;a href=&#34;https://www.lazyvim.org/configuration/tips#navigating-around-multiple-buffers&#34;&gt;a very nice way to deal with buffers&lt;/a&gt; - Use &lt;code&gt;H&lt;/code&gt; and &lt;code&gt;L&lt;/code&gt; if the buffer you want to go to is visually close to where you are. - Otherwise, if the buffer is open, use &lt;code&gt;&amp;lt;leader&amp;gt;,&lt;/code&gt; - For other files, use &lt;code&gt;&amp;lt;leader&amp;gt;&amp;lt;space&amp;gt;&lt;/code&gt; - Close buffers you no longer need with &lt;code&gt;&amp;lt;leader&amp;gt;bd&lt;/code&gt; - &lt;code&gt;&amp;lt;leader&amp;gt;ss&lt;/code&gt; to quickly jump to a function in the buffer you&#39;re on - Using the &lt;a href=&#34;#Using-the-jump-list&#34;&gt;jump list&lt;/a&gt; with &lt;code&gt;&amp;lt;c-o&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;c-i&amp;gt;&lt;/code&gt; and &lt;code&gt;gd&lt;/code&gt; to navigate the code - You can pin buffers with &lt;code&gt;&amp;lt;leader&amp;gt;bp&lt;/code&gt; and delete all non pinned buffers with &lt;code&gt;&amp;lt;leader&amp;gt;bP&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_movement/#using-the-jump-list&#34;&gt;Using the jump list.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Vim has a feature called the “Jump List”, which saves all the locations you’ve recently visited, including their line number, column number, and what else not in the &lt;code&gt;.viminfo&lt;/code&gt; file, to help you get exactly the position you were last in. Not only does it save the locations in your current buffer, but also previous buffers you may have edited in other Vim sessions. Which means, if you’re currently working on a file, and there aren’t many last-location saves in this one, you’ll be redirected to the previous file you had edited. But how do you do that? Simply press &lt;code&gt;Ctrl + O&lt;/code&gt;, and it’ll get you back to the previous location you were in, or more specifically, your cursor was in.&lt;/p&gt; &lt;p&gt;If you want to go back to the newer positions, after you’re done with what you wanted to do, you can then press &lt;code&gt;Ctrl + i&lt;/code&gt; to go back to the newer position. This is exceptionally useful when you’re working with a lot of project files at a time, and you need to go back and forth between multiple blocks in different files. This could instantly give you a boost, as you won’t need to have separate buffers opened up or windows to be setted up, you can simply jump between the files and edit them.&lt;/p&gt; &lt;p&gt;Ctrl + O is probably not meant for a single task, as far as Vim’s philosophy is concerned. The jumping mentioned in the previous section only works when you’re in Normal Mode, and not when you’re in Insert Mode. When you press Ctrl + O in Insert Mode, what happens instead is that you’ll enter Normal Mode, and be able to execute a single command, after which Vim will automatically switch back to Insert Mode.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/diffview/#using-lazyvim&#34;&gt;Install using Lazyvim.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;sindrets/diffview.nvim&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;dependencies&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;nvim-tree/nvim-web-devicons&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;lazy&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;dv&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;diffview.lib&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;views&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;DiffviewOpen&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;else&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;DiffviewClose&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Toggle Diffview window&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Which sets the next bindings: - &lt;code&gt;dv&lt;/code&gt;: &lt;a href=&#34;https://www.reddit.com/r/neovim/comments/15remc4/how_to_exit_all_the_tabs_in_diffviewnvim/?rdt=52076&#34;&gt;Toggle the opening and closing of the diffview windows&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/diffview/#use-diffview-as-merge-tool&#34;&gt;Use diffview as merge tool.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Add to your &lt;code&gt;~/.gitconfig&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[alias]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;mergetool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;!nvim -c DiffviewOpen&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/diffview/#resolve-merge-conflicts&#34;&gt;Resolve merge conflicts.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you call &lt;code&gt;:DiffviewOpen&lt;/code&gt; during a merge or a rebase, the view will list the conflicted files in their own section. When opening a conflicted file, it will open in a 3-way diff allowing you to resolve the conflict with the context of the target branch&#39;s version (OURS, left), and the version from the branch which is being merged (THEIRS, right).&lt;/p&gt; &lt;p&gt;The conflicted file&#39;s entry in the file panel will show the remaining number of conflict markers (the number following the file name). If what follows the file name is instead an exclamation mark (&lt;code&gt;!&lt;/code&gt;), this indicates that the file has not yet been opened, and the number of conflicts is unknown. If the sign is a check mark, this indicates that there are no more conflicts in the file.&lt;/p&gt; &lt;p&gt;You can interact with the merge tool with the next bindings:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;]x&lt;/code&gt; and &lt;code&gt;[x&lt;/code&gt;: Jump between conflict markers. This works from the file panel as well.&lt;/li&gt; &lt;li&gt;&lt;code&gt;dp&lt;/code&gt;: Put the contents on the other buffer&lt;/li&gt; &lt;li&gt;&lt;code&gt;do&lt;/code&gt;: Get the contents from the other buffer&lt;/li&gt; &lt;li&gt;&lt;code&gt;2do&lt;/code&gt;: to obtain the hunk from the OURS side of the diff&lt;/li&gt; &lt;li&gt;&lt;code&gt;3do&lt;/code&gt; to obtain the hunk from the THEIRS side of the diff&lt;/li&gt; &lt;li&gt;&lt;code&gt;1do&lt;/code&gt; to obtain the hunk from the BASE in a 4-way diff&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Additionally there are mappings for operating directly on the conflict markers:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;&amp;lt;leader&amp;gt;co&lt;/code&gt;: Choose the OURS version of the conflict.&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;leader&amp;gt;ct&lt;/code&gt;: Choose the THEIRS version of the conflict.&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;leader&amp;gt;cb&lt;/code&gt;: Choose the BASE version of the conflict.&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;leader&amp;gt;ca&lt;/code&gt;: Choose all versions of the conflict (effectively just deletes the markers, leaving all the content).&lt;/li&gt; &lt;li&gt;&lt;code&gt;dx&lt;/code&gt;: Choose none of the versions of the conflict (delete the conflict region).&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce ai coding prompts.&lt;/p&gt; &lt;p&gt;These are some useful AI prompts to help you while you code:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;create a function with type hints and docstring using google style called { } that { }&lt;/li&gt; &lt;li&gt;create the tests for the function { } adding type hints and following the AAA style where the Act section is represented contains a returns = (thing to test) line or if the function to test doesn&#39;t return any value append an # act comment at the end of the line. Use paragraphs to separate the AAA blocks and don&#39;t add comments inside the tests for the sections&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;If you use &lt;a href=&#34;https://lyz-code.github.io/blue-book/espanso/&#34;&gt;espanso&lt;/a&gt; you can simplify the filling up of these prompts on the AI chats. For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;matches&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;trigger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;:function&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;form&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;Create a function with type hints and docstring using google style called [[name]] that:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;[[text]]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;form_fields&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;multiline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;trigger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;:tweak&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;form&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;Tweak the next code:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;[[code]]&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;So that:&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;[[text]]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;form_fields&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;multiline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;code&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;multiline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;trigger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;:test&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;form&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;create the tests for the function:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;[[text]]&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;Following the next guidelines:&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;- Add type hints&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;- Follow the AAA style&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;- In the Act section if the function to test returns a value always name that variable returns. If the function to test doesn&#39;t return any value append an # act comment at the end of the line.&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;- Use paragraphs to separate the AAA blocks and don&#39;t add comments like # Arrange or # Act or # Act/Assert or # Assert&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;form_fields&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;multiline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;trigger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;:refactor&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;form&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;Refactor the next code&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;[[code]]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;with the next conditions&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;[[conditions]]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;form_fields&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;code&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;multiline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;conditions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;multiline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce Kestra.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://kestra.io/&#34;&gt;Kestra&lt;/a&gt; is an &lt;a href=&#34;data_orchestrator.md&#34;&gt;open-source orchestrator&lt;/a&gt; designed to bring Infrastructure as Code (IaC) best practices to all workflows — from those orchestrating mission-critical operations, business processes, and data pipelines to simple Zapier-style automation. Built with an API-first philosophy, Kestra enables users to define and manage data pipelines through a simple YAML configuration file. This approach frees you from being tied to a specific client implementation, allowing for greater flexibility and easier integration with various tools and services.&lt;/p&gt; &lt;p&gt;Look at this &lt;a href=&#34;https://www.youtube.com/watch?v=h-P0eK2xN58&#34;&gt;4 minute video&lt;/a&gt; for a visual introduction&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt; - &lt;a href=&#34;https://kestra.io/docs/getting-started&#34;&gt;Docs&lt;/a&gt; - &lt;a href=&#34;https://kestra.io/&#34;&gt;Home&lt;/a&gt; - &lt;a href=&#34;https://www.youtube.com/watch?v=h-P0eK2xN58&#34;&gt;4 minute introduction video&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add new prompts for developers.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;trigger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;:polish&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;form&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;Polish the next code&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;[[code]]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;with the next conditions:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;- Use type hints on all functions and methods&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;- Add or update the docstring using google style on all functions and methods&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;form_fields&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;code&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;multiline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;trigger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;:commit&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;form&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;Act as an expert developer. Create a message commit with the next conditions:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;- follow semantic versioning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;- create a semantic version comment per change&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;- include all comments in a raw code block so that it&#39;s easy to copy&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;for the following diff&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;[[text]]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;form_fields&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;multiline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Update the ai prompts.&lt;/p&gt; &lt;p&gt;```yaml matches: - trigger: :function form: | Create a function with: - type hints - docstrings for all classes, functions and methods - docstring using google style with line length less than 89 characters - adding logging traces using the log variable log = logging.getLogger(&lt;strong&gt;name&lt;/strong&gt;) - Use fstrings instead of %s - If you need to open or write a file always set the encoding to utf8 - If possible add an example in the docstring - Just give the code, don&#39;t explain anything&lt;/p&gt; &lt;pre&gt;&lt;code&gt;  Called [[name]] that:
  [[text]]
form_fields:
  text:
    multiline: true
&lt;/code&gt;&lt;/pre&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;trigger: :class form: | Create a class with:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;type hints&lt;/li&gt; &lt;li&gt;docstring using google style with line length less than 89 characters&lt;/li&gt; &lt;li&gt;use docstrings on the class and each methods&lt;/li&gt; &lt;li&gt;adding logging traces using the log variable log = logging.getLogger(&lt;strong&gt;name&lt;/strong&gt;)&lt;/li&gt; &lt;li&gt;Use fstrings instead of %s&lt;/li&gt; &lt;li&gt;If you need to open or write a file always set the encoding to utf8&lt;/li&gt; &lt;li&gt;If possible add an example in the docstring&lt;/li&gt; &lt;li&gt;Just give the code, don&#39;t explain anything&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Called [[name]] that: [[text]] form_fields: text: - trigger: :class form: | ... - Use paragraphs to separate the AAA blocks and don&#39;t add comments like # Arrange or # Act or # Act/Assert or # Assert. So the test will only have black lines between sections - In the Act section if the function to test returns a value always name that variable result. If the function to test doesn&#39;t return any value append an # act comment at the end of the line. - If the test uses a pytest.raises there is no need to add the # act comment - Don&#39;t use mocks - Use fstrings instead of %s - Gather all tests over the same function on a common class - If you need to open or write a file always set the encoding to utf8 - Just give the code, don&#39;t explain anything&lt;/p&gt; &lt;p&gt;form_fields: text: - trigger: :polish form: | ... - Add or update the docstring using google style on all classes, functions and methods - Wrap the docstring lines so they are smaller than 89 characters - All docstrings must start in the same line as the &#34;&#34;&#34; - Add logging traces using the log variable log = logging.getLogger(&lt;strong&gt;name&lt;/strong&gt;) - Use f-strings instead of %s - Just give the code, don&#39;t explain anything form_fields: code: multiline: true - trigger: :text form: | Polish the next text by:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Summarising each section without losing relevant data&lt;/li&gt; &lt;li&gt;Tweak the markdown format&lt;/li&gt; &lt;li&gt;Improve the wording&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;[[text]] form_fields: text: multiline: true&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;trigger: :readme form: | Create the README.md taking into account:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Use GPLv3 for the license&lt;/li&gt; &lt;li&gt;Add Lyz as the author&lt;/li&gt; &lt;li&gt;Add an installation section&lt;/li&gt; &lt;li&gt;Add an usage section&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;of: [[text]]&lt;/p&gt; &lt;p&gt;form_fields: text: multiline: true ``` feat(aleph#Get all documents of a collection): Get all documents of a collection&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;code&gt;list_aleph_collection_documents.py&lt;/code&gt; is a Python script designed to interact with an API to retrieve and analyze documents from specified collections. It offers a command-line interface (CLI) to list and check documents within a specified collection.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Features&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Retrieve documents from a specified collection.&lt;/li&gt; &lt;li&gt;Analyze document processing statuses and warn if any are not marked as successful.&lt;/li&gt; &lt;li&gt;Return a list of filenames from the retrieved documents.&lt;/li&gt; &lt;li&gt;Supports verbose output for detailed logging.&lt;/li&gt; &lt;li&gt;Environment variable support for API key management.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To install the required dependencies, use &lt;code&gt;pip&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;typer&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;requests
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Ensure you have Python 3.6 or higher installed.&lt;/p&gt; &lt;p&gt;Create the file &lt;code&gt;list_aleph_collection_documents.py&lt;/code&gt; with the next contents:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;logging&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;requests&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;typing&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Any&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Optional&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;logging&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;typer&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;typing&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Any&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;log&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getLogger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;app&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;typer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Typer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

&lt;span class=&#34;nd&#34;&gt;@app&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;get_documents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;collection_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;typer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;api_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Optional&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;typer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Option&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;envvar&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;API_KEY&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;base_url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;typer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Option&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;https://your.aleph.org&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;verbose&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bool&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;typer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Option&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;--verbose&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;-v&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;help&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Enable verbose output&#34;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;CLI command to retrieve documents from a specified collection.&#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;verbose&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;basicConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DEBUG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;debug&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Verbose mode enabled.&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;basicConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INFO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;api_key&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&#34;Please specify your api key either through the --api-key argument &#34;&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&#34;or through the API_KEY environment variable&#34;&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;typer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Exit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;code&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;documents&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;list_collection_documents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;base_url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;collection_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;filenames&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;check_documents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;documents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filenames&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;join&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;filenames&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;warning&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;No documents found.&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;Exception&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed to retrieve documents: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;typer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Exit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;code&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;list_collection_documents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;api_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;base_url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;collection_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Any&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    Retrieve documents from a specified collection using pagination.&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;    Args:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        api_key (str): The API key for authentication.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        base_url (str): The base URL of the API.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        collection_name (str): The name of the collection to retrieve documents from.&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;    Returns:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        List[Dict[str, Any]]: A list of documents from the specified collection.&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;    Example:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        &amp;gt;&amp;gt;&amp;gt; docs = list_collection_documents(&#34;your_api_key&#34;, &#34;https://api.example.com&#34;, &#34;my_collection&#34;)&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        &amp;gt;&amp;gt;&amp;gt; print(len(docs))&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        1000&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    &#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;Authorization&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;ApiKey &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api_key&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;Accept&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;application/json&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;Content-Type&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;application/json&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;collections_url&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;base_url&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/api/2/collections&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;documents_url&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;base_url&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/api/2/entities&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;debug&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Requesting collections list from &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;collections_url&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;collections&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;params&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;limit&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;300&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;requests&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;collections_url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;params&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;raise_for_status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;collections&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;extend&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;results&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;debug&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Fetched &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;results&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; collections, &#34;&lt;/span&gt;
            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;page &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;page&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; of &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;pages&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;next&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;offset&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;params&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;offset&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;limit&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;collection_id&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;id&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;c&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;collections&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;label&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;collection_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;collection_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Collection &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;collection_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; not found.&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Found collection &#39;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;collection_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#39; with ID &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;collection_id&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;documents&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;params&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;q&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;filter:collection_id&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;collection_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;filter:schemata&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Document&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;limit&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;300&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;debug&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Requesting documents from collection &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;collection_id&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;requests&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;documents_url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;params&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;raise_for_status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;documents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;extend&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;results&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Fetched &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;results&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; documents, &#34;&lt;/span&gt;
            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;page &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;page&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; of &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;pages&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;next&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;offset&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;params&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;offset&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;limit&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Retrieved &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;documents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; documents from collection &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;collection_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;documents&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;check_documents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;documents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Any&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]])&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Analyze the processing status of documents and return a list of filenames.&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;    Args:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        documents (List[Dict[str, Any]]): A list of documents in JSON format.&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;    Returns:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        List[str]: A list of filenames from documents with a successful processing status.&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;    Raises:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        None, but logs warnings if a document&#39;s processing status is not &#39;success&#39;.&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;    Example:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        &amp;gt;&amp;gt;&amp;gt; docs = [{&#34;properties&#34;: {&#34;processingStatus&#34;: [&#34;success&#34;], &#34;fileName&#34;: [&#34;file1.txt&#34;]}},&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        &amp;gt;&amp;gt;&amp;gt;         {&#34;properties&#34;: {&#34;processingStatus&#34;: [&#34;failed&#34;], &#34;fileName&#34;: [&#34;file2.txt&#34;]}}]&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        &amp;gt;&amp;gt;&amp;gt; filenames = check_documents(docs)&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        &amp;gt;&amp;gt;&amp;gt; print(filenames)&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        [&#39;file1.txt&#39;]&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    &#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;filenames&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;doc&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;documents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;status&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;doc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;properties&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{})&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;processingStatus&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;doc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;properties&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{})&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;fileName&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;

        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;status&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;success&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;warning&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Document with filename &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; has processing status: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;status&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;filenames&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;debug&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Collected filenames: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;filenames&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filenames&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;__main__&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;app&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;em&gt;Get your API key&lt;/em&gt;&lt;/p&gt; &lt;p&gt;By default, any Aleph search will return only public documents in responses to API requests.&lt;/p&gt; &lt;p&gt;If you want to access documents which are not marked public, you will need to sign into the tool. This can be done through the use on an API key. The API key for any account can be found by clicking on the &#34;Settings&#34; menu item in the navigation menu.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can run the script directly from the command line. Below are examples of usage:&lt;/p&gt; &lt;p&gt;Retrieve and list documents from a collection:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;python&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list_aleph_collection_documents.py&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--api-key&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;your-api-key&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Name of your collection&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Using an Environment Variable for the API Key&lt;/p&gt; &lt;p&gt;This is better from a security perspective. &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;API_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your_api_key
python&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list_aleph_collection_documents.py&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Name of your collection&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;Enabling Verbose Logging&lt;/p&gt; &lt;p&gt;To enable detailed debug logs, use the &lt;code&gt;--verbose&lt;/code&gt; or &lt;code&gt;-v&lt;/code&gt; flag:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;python&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list_aleph_collection_documents.py&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Name of your collection&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Getting help&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;python&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list_aleph_collection_documents.py&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--help
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;memorious&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_tabs/&#34;&gt;memorious&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_tabs/#switch-to-the-previous-opened-buffer&#34;&gt;Switch to the previous opened buffer.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Often the buffer that you want to edit is the buffer that you have just left. Vim provides a couple of convenient commands to switch back to the previous buffer. These are &lt;code&gt;&amp;lt;C-^&amp;gt;&lt;/code&gt; (or &lt;code&gt;&amp;lt;C-6&amp;gt;&lt;/code&gt;) and &lt;code&gt;:b#&lt;/code&gt;. All of them are inconvenient so I use the next mapping:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;nnoremap&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;Leader&lt;span class=&#34;p&#34;&gt;&amp;gt;&amp;lt;&lt;/span&gt;Tab&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt; :&lt;span class=&#34;k&#34;&gt;b&lt;/span&gt;#&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;CR&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_lsp/#undefined-global-vim-warning&#34;&gt;Troubleshoot Undefined global &lt;code&gt;vim&lt;/code&gt; warning.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Added to my lua/plugins directory:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;neovim/nvim-lspconfig&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;opts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;servers&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;lua_ls&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;settings&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;Lua&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
              &lt;span class=&#34;n&#34;&gt;diagnostics&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;globals&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;vim&#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
              &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
          &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_packer/#get-the-version-of-the-packages-installed-by-packer&#34;&gt;Get the version of the packages installed by Packer.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Go into the plugin directory &lt;code&gt;cd ~/.local/share/nvim/site/pack/packer/start/your-plugin&lt;/code&gt; and check it with git&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce memorious.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/alephdata/memorious&#34;&gt;Memorious&lt;/a&gt; is a light-weight web scraping toolkit. It supports scrapers that collect structured or un-structured data. This includes the following use cases:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Make crawlers modular and simple tasks re-usable&lt;/li&gt; &lt;li&gt;Provide utility functions to do common tasks such as data storage, HTTP session management&lt;/li&gt; &lt;li&gt;Integrate crawlers with the Aleph and FollowTheMoney ecosystem&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/alephdata/memorious&#34;&gt;Memorious&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;data-orchestrators&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/&#34;&gt;Data orchestrators&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Update disable regular login with oauth.&lt;/p&gt; &lt;p&gt;The last &lt;code&gt;signin_inner.tmpl&lt;/code&gt; failed with the latest version. I&#39;ve uploaded the new working one.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Configure vim to work with markdown.&lt;/p&gt; &lt;p&gt;Markdown specific plugins:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/jakewvincent/mkdnflow.nvim&#34;&gt;mkdnflow&lt;/a&gt; looks awesome.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_markdown/#enable-folds&#34;&gt;Enable folds.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you have set the &lt;code&gt;foldmethod&lt;/code&gt; to &lt;code&gt;indent&lt;/code&gt; by default you won&#39;t be able to use folds in markdown.&lt;/p&gt; &lt;p&gt;To fix this you can create the next autocommand (in &lt;code&gt;lua/config/autocmds.lua&lt;/code&gt; if you&#39;re using &lt;a href=&#34;https://lyz-code.github.io/blue-book/lazyvim/&#34;&gt;lazyvim&lt;/a&gt;).&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_create_autocmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;FileType&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;pattern&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;markdown&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;callback&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;foldmethod&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;expr&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;foldexpr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;v:lua.vim.treesitter.foldexpr()&#34;&lt;/span&gt;
  &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_markdown/#aligning-tables-in-markdown&#34;&gt;Aligning tables in markdown.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;In the past I used &lt;a href=&#34;https://github.com/godlygeek/tabular&#34;&gt;Tabular&lt;/a&gt; but it doesn&#39;t work with the latest neovim and the project didn&#39;t have any update in the last 5 years.&lt;/p&gt; &lt;p&gt;A good way to achieve this &lt;a href=&#34;https://heitorpb.github.io/bla/format-tables-in-vim/&#34;&gt;without installing any plugin is to&lt;/a&gt;:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;select the table, including the header and footer lines (with shift V, for example).&lt;/li&gt; &lt;li&gt;Prettify the table with &lt;code&gt;:!column -t -s &#39;|&#39; -o &#39;|&#39;&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;If you don&#39;t want to remember that command you can bind it to a key:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;v&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;leader&amp;gt;tf&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;!column -t -s &#39;|&#39; -o &#39;|&#39;&amp;lt;cr&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Format table&#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;How the hell this works?&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;shift V&lt;/code&gt; switches to Visual mode linewise. This is to select all the lines of the table.&lt;/li&gt; &lt;li&gt;&lt;code&gt;:&lt;/code&gt; switches to Command line mode, to type commands.&lt;/li&gt; &lt;li&gt;&lt;code&gt;!&lt;/code&gt; specifies a filter command. This means we will send data to a command to modify it (or to filter) and replace the original lines. In this case we are in Visual mode, we defined the input text (the selected lines) and we will use an external command to modify the data.&lt;/li&gt; &lt;li&gt;&lt;code&gt;column&lt;/code&gt; is the filter command we are using, from the &lt;code&gt;util-linux&lt;/code&gt; package. column’s purpose is to “columnate”. The &lt;code&gt;-t&lt;/code&gt; flag tells column to use the Table mode. The &lt;code&gt;-s&lt;/code&gt; flag specifies the delimiters in the input data (the default is whitespace). And the &lt;code&gt;-o&lt;/code&gt; flag is to specify the output delimiter to use (we need that because the default is two whitespaces).&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#fix-server-does-not-allow-request-for-unadvertised-object-error&#34;&gt;Fix Server does not allow request for unadvertised object error.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Fetching the whole history with fetch-depth: 0 worked for us:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Checkout the codebase&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;actions/checkout@v3&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;fetch-depth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce data orchestrators.&lt;/p&gt; &lt;p&gt;Data orchestration is the process of moving siloed data from multiple storage locations into a centralized repository where it can then be combined, cleaned, and enriched for activation.&lt;/p&gt; &lt;p&gt;Data orchestrators are web applications that make this process easy. The most popular right now are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Apache Airflow&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#kestra&#34;&gt;Kestra&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Prefect&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;There are several comparison pages:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://medium.com/geekculture/airflow-vs-prefect-vs-kestra-which-is-best-for-building-advanced-data-pipelines-40cfbddf9697&#34;&gt;Geek Culture comparison&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://kestra.io/vs/airflow&#34;&gt;Kestra&#39;s comparison to Airflow&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://kestra.io/vs/prefect&#34;&gt;Kestra&#39;s comparison to Prefect&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;When looking at the return on investment when choosing an orchestration tool, there are several points to consider:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Time of installation/maintenance&lt;/li&gt; &lt;li&gt;Time to write pipeline&lt;/li&gt; &lt;li&gt;Time to execute (performance)&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/kestra/&#34;&gt;Kestra&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Pros:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Easier to write pipelines&lt;/li&gt; &lt;li&gt;Nice looking web UI&lt;/li&gt; &lt;li&gt;It has a &lt;a href=&#34;https://kestra.io/docs/getting-started/terraform&#34;&gt;terraform provider&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://kestra.io/docs/how-to-guides/monitoring&#34;&gt;Prometheus and grafana integration&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Cons:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Built in Java, so extending it might be difficult&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://kestra.io/docs/developer-guide/plugins&#34;&gt;Plugins are made in Java&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Kestra offers a higher ROI globally compared to Airflow:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Installing Kestra is easier than Airflow; it doesn’t require Python dependencies, and it comes with a ready-to-use docker-compose file using few services and without the need to understand what’s an executor to run task in parallel.&lt;/li&gt; &lt;li&gt;Creating pipelines with Kestra is simple, thanks to its syntax. You don’t need knowledge of a specific programming language because Kestra is designed to be agnostic. The declarative YAML design makes Kestra flows more readable compared to Airflow’s DAG equivalent, allowing developers to significantly reduce development time.&lt;/li&gt; &lt;li&gt;In this benchmark, Kestra demonstrates better execution time than Airflow under any configuration setup.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;scrapers&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_plugin_development/&#34;&gt;Scrapers&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Debug Adapter Protocol.&lt;/p&gt; &lt;p&gt;&lt;code&gt;nvim-dap&lt;/code&gt;](&lt;a href=&#34;https://github.com/mfussenegger/nvim-dap&#34;&gt;https://github.com/mfussenegger/nvim-dap&lt;/a&gt;) implements a client for the &lt;a href=&#34;https://microsoft.github.io/debug-adapter-protocol/overview&#34;&gt;Debug Adapter Protocol&lt;/a&gt;. This allows a client to control a debugger over a documented API. That allows us to control the debugger from inside neovim, being able to set breakpoints, evaluate runtime values of variables, and much more.&lt;/p&gt; &lt;p&gt;&lt;code&gt;nvim-dap&lt;/code&gt; is not configured for any language by default. You will need to set up a configuration for each language. For the configurations you will need adapters to run.&lt;/p&gt; &lt;p&gt;I would suggest starting with 2 actions. Setting breakpoints and “running” the debugger. The debugger allows us to stop execution and look at the current state of the program. Setting breakpoints will allow us to stop execution and see what the current state is.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;b&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[:lua require&#34;dap&#34;.toggle_breakpoint()&amp;lt;CR&amp;gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;c&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[:lua require&#34;dap&#34;.continue()&amp;lt;CR&amp;gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[:lua require&#34;dap&#34;.step_over()&amp;lt;CR&amp;gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;N&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[:lua require&#34;dap&#34;.step_into()&amp;lt;CR&amp;gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;F5&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[:lua require&#34;osv&#34;.launch({port = 8086})&amp;lt;CR&amp;gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Go to a line where a conditional or value is set and toggle a breakpoint. Then, we’ll start the debugger. If done correctly, you’ll see an arrow next to your line of code you set a breakpoint at.&lt;/p&gt; &lt;p&gt;There is no UI with dap by default. You have a few options for UI &lt;a href=&#34;https://github.com/rcarriga/nvim-dap-ui&#34;&gt;nvim-dap-ui&lt;/a&gt;&lt;/p&gt; &lt;p&gt;In the &lt;code&gt;dap&lt;/code&gt; repl you can &lt;a href=&#34;https://github.com/mfussenegger/nvim-dap/blob/master/doc/dap.txt&#34;&gt;use the next operations&lt;/a&gt;:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;.exit&lt;/code&gt;: Closes the REPL&lt;/li&gt; &lt;li&gt;&lt;code&gt;.c&lt;/code&gt; or &lt;code&gt;.continue&lt;/code&gt;: Same as |&lt;code&gt;dap.continue&lt;/code&gt;|&lt;/li&gt; &lt;li&gt;&lt;code&gt;.n&lt;/code&gt; or &lt;code&gt;.next&lt;/code&gt;: Same as |&lt;code&gt;dap.step_over&lt;/code&gt;|&lt;/li&gt; &lt;li&gt;&lt;code&gt;.into&lt;/code&gt;: Same as |&lt;code&gt;dap.step_into&lt;/code&gt;|&lt;/li&gt; &lt;li&gt;&lt;code&gt;.into_target&lt;/code&gt;: Same as |&lt;code&gt;dap.step_into{askForTargets=true}&lt;/code&gt;|&lt;/li&gt; &lt;li&gt;&lt;code&gt;.out&lt;/code&gt;: Same as |&lt;code&gt;dap.step_out&lt;/code&gt;|&lt;/li&gt; &lt;li&gt;&lt;code&gt;.up&lt;/code&gt;: Same as |&lt;code&gt;dap.up&lt;/code&gt;|&lt;/li&gt; &lt;li&gt;&lt;code&gt;.down&lt;/code&gt;: Same as |&lt;code&gt;dap.down&lt;/code&gt;|&lt;/li&gt; &lt;li&gt;&lt;code&gt;.goto&lt;/code&gt;: Same as |&lt;code&gt;dap.goto_&lt;/code&gt;|&lt;/li&gt; &lt;li&gt;&lt;code&gt;.scopes&lt;/code&gt;: Prints the variables in the current s&lt;code&gt;cope&lt;/code&gt;s&lt;/li&gt; &lt;li&gt;&lt;code&gt;.threads&lt;/code&gt;: Prints all t&lt;code&gt;hread&lt;/code&gt;s&lt;/li&gt; &lt;li&gt;&lt;code&gt;.frames&lt;/code&gt;: Print the stack f&lt;code&gt;rame&lt;/code&gt;s&lt;/li&gt; &lt;li&gt;&lt;code&gt;.capabilities&lt;/code&gt;: Print the capabilities of the debug a&lt;code&gt;dapte&lt;/code&gt;r&lt;/li&gt; &lt;li&gt;&lt;code&gt;.b&lt;/code&gt; or &lt;code&gt;.back&lt;/code&gt;: Same as |&lt;code&gt;dap.step_back&lt;/code&gt;|&lt;/li&gt; &lt;li&gt;&lt;code&gt;.rc&lt;/code&gt; or &lt;code&gt;.reverse-continue&lt;/code&gt;: Same as |&lt;code&gt;dap.reverse_continue&lt;/code&gt;|&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_dap/#nvim-dap-ui&#34;&gt;Introduce nvim-dap-ui.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Install with packer:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;rcarriga/nvim-dap-ui&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;requires&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;mfussenegger/nvim-dap&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;It is highly recommended to use &lt;a href=&#34;https://github.com/folke/neodev.nvim&#34;&gt;&lt;code&gt;neodev.nvim&lt;/code&gt;&lt;/a&gt; to enable type checking for &lt;code&gt;nvim-dap-ui&lt;/code&gt; to get type checking, documentation and autocompletion for all API functions.&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;neodev&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;library&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;plugins&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;nvim-dap-ui&#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;types&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;code&gt;nvim-dap-ui&lt;/code&gt; is built on the idea of &#34;elements&#34;. These elements are windows which provide different features.&lt;/p&gt; &lt;p&gt;Elements are grouped into layouts which can be placed on any side of the screen. There can be any number of layouts, containing whichever elements desired.&lt;/p&gt; &lt;p&gt;Elements can also be displayed temporarily in a floating window.&lt;/p&gt; &lt;p&gt;Each element has a set of mappings for element-specific possible actions, detailed below for each element. The total set of actions/mappings and their default shortcuts are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;edit: &lt;code&gt;e&lt;/code&gt;&lt;/li&gt; &lt;li&gt;expand: &lt;code&gt;&amp;lt;CR&amp;gt;&lt;/code&gt; or left click&lt;/li&gt; &lt;li&gt;open: &lt;code&gt;o&lt;/code&gt;&lt;/li&gt; &lt;li&gt;remove: &lt;code&gt;d&lt;/code&gt;&lt;/li&gt; &lt;li&gt;repl: &lt;code&gt;r&lt;/code&gt;&lt;/li&gt; &lt;li&gt;toggle: &lt;code&gt;t&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;See &lt;code&gt;:h dapui.setup()&lt;/code&gt; for configuration options and defaults.&lt;/p&gt; &lt;p&gt;To get started simply call the setup method on startup, optionally providing custom settings.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;dapui&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can open, close and toggle the windows with corresponding functions:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;dapui&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;dapui&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;dapui&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;toggle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_dap/#one-small-step-for-vimkind&#34;&gt;Debug neovim plugins with DAP.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;one-small-step-for-vimkind&lt;/code&gt; is an adapter for the Neovim lua language. It allows you to debug any lua code running in a Neovim instance.&lt;/p&gt; &lt;p&gt;Install it with Packer:&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;mfussenegger/nvim-dap&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; After installing one-small-step-for-vimkind, you will also need a DAP plugin which will allow you to interact with the adapter. Check the install instructions &lt;a href=&#34;#nvim-dap&#34;&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Then add these lines to your config:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;dap&#34;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;dap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;configurations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lua&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;nlua&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;request&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;attach&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Attach to running Neovim instance&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;dap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;adapters&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nlua&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;callback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;callback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;server&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;host&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;host&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;127.0.0.1&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;port&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;port&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;8086&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_plugin_development/#debugging-with-dap&#34;&gt;Debugging with DAP.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can debug Lua code running in a separate Neovim instance with &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_dap/#one-small-step-for-vimkind&#34;&gt;jbyuki/one-small-step-for-vimkind&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;The plugin uses the &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_dap/#debug-adapter-protocol&#34;&gt;Debug Adapter Protocol&lt;/a&gt;. Connecting to a debug adapter requires a DAP client like &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_dap/#nvim-dap&#34;&gt;mfussenegger/nvim-dap&lt;/a&gt;. Check how to configure &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_dap/#one-small-step-for-vimkind&#34;&gt;here&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Once you have all set up and assuming you&#39;re using the next keybindings for &lt;code&gt;nvim-dap&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;b&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[:lua require&#34;dap&#34;.toggle_breakpoint()&amp;lt;CR&amp;gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;c&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[:lua require&#34;dap&#34;.continue()&amp;lt;CR&amp;gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[:lua require&#34;dap&#34;.step_over()&amp;lt;CR&amp;gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;N&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[:lua require&#34;dap&#34;.step_into()&amp;lt;CR&amp;gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;F5&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[:lua require&#34;osv&#34;.launch({port = 8086})&amp;lt;CR&amp;gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;B&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[:lua require&#34;dapui&#34;.toggle()&amp;lt;CR&amp;gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You will debug the plugin by:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Launch the server in the debuggee using &lt;code&gt;F5&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;Open another Neovim instance with the source file (the debugger).&lt;/li&gt; &lt;li&gt;Place breakpoint with &lt;code&gt;&amp;lt;leader&amp;gt;b&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;On the debugger connect to the DAP client with &lt;code&gt;&amp;lt;leader&amp;gt;c&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;Optionally open the &lt;code&gt;nvim-dap-ui&lt;/code&gt; with &lt;code&gt;&amp;lt;leader&amp;gt;B&lt;/code&gt; in the debugger.&lt;/li&gt; &lt;li&gt;Run your script/plugin in the debuggee&lt;/li&gt; &lt;li&gt;Interact in the debugger using &lt;code&gt;&amp;lt;leader&amp;gt;n&lt;/code&gt; to step to the next step, and &lt;code&gt;&amp;lt;leader&amp;gt;N&lt;/code&gt; to step into. Then use the dap console to inspect and change the values of the state.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce morph.io.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://morph.io/&#34;&gt;morph.io&lt;/a&gt; is a web service that runs your scrapers for you.&lt;/p&gt; &lt;p&gt;Write your scraper in the language you know and love, push your code to GitHub, and they take care of the boring bits. Things like running your scraper regularly, alerting you if there&#39;s a problem, storing your data, and making your data available for download or through a super-simple API.&lt;/p&gt; &lt;p&gt;To sign in you&#39;ll need a GitHub account. This is where your scraper code is stored.&lt;/p&gt; &lt;p&gt;The data is stored in an sqlite&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Usage limits&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Right now there are very few limits. They are trusting you that you won&#39;t abuse this.&lt;/p&gt; &lt;p&gt;However, they do impose a couple of hard limits on running scrapers so they don&#39;t take up too many resources&lt;/p&gt; &lt;ul&gt; &lt;li&gt;max 512 MB memory&lt;/li&gt; &lt;li&gt;max 24 hours run time for a single run&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;If a scraper runs out of memory or runs too long it will get killed automatically.&lt;/p&gt; &lt;p&gt;There&#39;s also a soft limit:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;max 10,000 lines of log output&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;If a scraper generates more than 10,000 lines of log output the scraper will continue running uninterrupted. You just won&#39;t see any more output than that. To avoid this happening simply print less stuff to the screen.&lt;/p&gt; &lt;p&gt;Note that they are keeping track of the amount of cpu time (and a whole bunch of other metrics) that you and your scrapers are using. So, if they do find that you are using too much they reserve the right to kick you out. In reality first they&#39;ll ask you nicely to stop.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://morph.io/documentation&#34;&gt;Docs&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://morph.io/&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;vim-autosave&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/git/&#34;&gt;Vim autosave&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Search for alternatives to git-sweep.&lt;/p&gt; &lt;p&gt;The tool is &lt;a href=&#34;https://github.com/arc90/git-sweep/issues/45&#34;&gt;no longer maintained&lt;/a&gt; but there is still no good alternative. I&#39;ve found some but are either not popular and/or not maintained:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/petems/gitsweeper&#34;&gt;gitsweeper&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/nemisj/git-removed-branches&#34;&gt;git-removed-brances&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/gottwald/git-sweep&#34;&gt;git-sweep rewrite in go&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/git/#update-all-git-submodules&#34;&gt;Update all git submodules.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If it&#39;s the first time you check-out a repo you need to use &lt;code&gt;--init&lt;/code&gt; first:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;submodule&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--init&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--recursive
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To update to latest tips of remote branches use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;submodule&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--recursive&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--remote
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Manually toggle the autosave function.&lt;/p&gt; &lt;p&gt;Besides running auto-save at startup (if you have &lt;code&gt;enabled = true&lt;/code&gt; in your config), you may as well:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;ASToggle&lt;/code&gt;: toggle auto-save&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;espanso&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/espanso/&#34;&gt;Espanso&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce espanso.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/espanso/espanso&#34;&gt;Espanso&lt;/a&gt; is a cross-platform Text Expander written in Rust.&lt;/p&gt; &lt;p&gt;A text expander is a program that detects when you type a specific keyword and replaces it with something else. This is useful in many ways:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Save a lot of typing, expanding common sentences or fixing common typos.&lt;/li&gt; &lt;li&gt;Create system-wide code snippets.&lt;/li&gt; &lt;li&gt;Execute custom scripts&lt;/li&gt; &lt;li&gt;Use emojis like a pro.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://espanso.org/docs/install/linux/&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt; Espanso ships with a .deb package, making the installation convenient on Debian-based systems.&lt;/p&gt; &lt;p&gt;Start by downloading the package by running the following command inside a terminal:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;wget&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://github.com/federico-terzi/espanso/releases/download/v2.2.1/espanso-debian-x11-amd64.deb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can now install the package using:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;./espanso-debian-x11-amd64.deb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;From now on, you should have the &lt;code&gt;espanso&lt;/code&gt; command available in the terminal (you can verify by running &lt;code&gt;espanso --version&lt;/code&gt;).&lt;/p&gt; &lt;p&gt;At this point, you are ready to use &lt;code&gt;espanso&lt;/code&gt; by registering it first as a Systemd service and then starting it with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;espanso&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;service&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;register
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Start espanso&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;espanso&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Espanso ships with very few built-in matches to give you the maximum flexibility, but you can expand its capabilities in two ways: creating your own custom matches or &lt;a href=&#34;#using-packages&#34;&gt;installing packages&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://espanso.org/docs/get-started/#configuration&#34;&gt;Configuration&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Your configuration lives at &lt;code&gt;~/.config/espanso&lt;/code&gt;. A quick way to find the path of your configuration folder is by using the following command &lt;code&gt;espanso path&lt;/code&gt;.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The files contained in the &lt;code&gt;match&lt;/code&gt; directory define what Espanso should do. In other words, this is where you should specify all the custom snippets and actions (aka Matches). The &lt;code&gt;match/base.yml&lt;/code&gt; file is where you might want to start adding your matches.&lt;/li&gt; &lt;li&gt;The files contained in the &lt;code&gt;config&lt;/code&gt; directory define how Espanso should perform its expansions. In other words, this is were you should specify all Espanso&#39;s parameters and options. The &lt;code&gt;config/default.yml&lt;/code&gt; file defines the options that will be applied to all applications by default, unless an app-specific configuration is present for the current app.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://espanso.org/docs/get-started/#understanding-packages&#34;&gt;Using packages&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Custom matches are great, but sometimes it can be tedious to define them for every common operation, especially when you want to share them with other people.&lt;/p&gt; &lt;p&gt;Espanso offers an easy way to share and reuse matches with other people, packages. In fact, they are so important that Espanso includes a built-in package manager and a store, the &lt;a href=&#34;https://hub.espanso.org/&#34;&gt;Espanso Hub&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://espanso.org/docs/get-started/#installing-a-package&#34;&gt;Installing a package&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Get the id of the package from the &lt;a href=&#34;https://hub.espanso.org/&#34;&gt;Espanso Hub&lt;/a&gt; and then run &lt;code&gt;espanso install &amp;lt;&amp;lt;package_name&amp;gt;&amp;gt;&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Of all the packages, I&#39;ve found the next ones the most useful:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://hub.espanso.org/typofixer-en&#34;&gt;typofixer-en&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://hub.espanso.org/typofixer-es&#34;&gt;typofixer-es&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://hub.espanso.org/misspell-en-uk&#34;&gt;misspell-en-uk&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Overwriting the snippets of a package&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;For example the &lt;code&gt;typofixer-en&lt;/code&gt; replaces &lt;code&gt;si&lt;/code&gt; to &lt;code&gt;is&lt;/code&gt;, although &lt;code&gt;si&lt;/code&gt; is a valid spanish word. To override the fix you can create your own file on &lt;code&gt;~/.config/espanso/match/typofix_overwrite.yml&lt;/code&gt; with the next content:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;matches&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Simple text replacement&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;trigger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;si&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;replace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;si&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://espanso.org/docs/packages/creating-a-package/&#34;&gt;Creating a package&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Auto-restart on config changes&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Set &lt;code&gt;auto_restart: true&lt;/code&gt; on &lt;code&gt;~/.config/espanso/config/default.yml&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://espanso.org/docs/configuration/options/#customizing-the-search-bar&#34;&gt;Changing the search bar shortcut&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If the default search bar shortcut conflicts with your i3 configuration set it with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;search_shortcut&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;CTRL+SHIFT+e&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://espanso.org/docs/configuration/options/#hiding-the-notifications&#34;&gt;Hiding the notifications&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can hide the notifications by adding the following option to your &lt;code&gt;$CONFIG/config/default.yml&lt;/code&gt; config:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;show_notifications&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Just type and you&#39;ll see the text expanded.&lt;/p&gt; &lt;p&gt;You can use the search bar if you don&#39;t remember your snippets.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt; - &lt;a href=&#34;https://github.com/espanso/espanso&#34;&gt;Code&lt;/a&gt; - &lt;a href=&#34;https://espanso.org/docs/get-started/&#34;&gt;Docs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/espanso/#desktop-application-to-add-words-easily&#34;&gt;Desktop application to add words easily.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Going into the espanso config files to add words is cumbersome, to make things easier you can use the &lt;code&gt;espansadd&lt;/code&gt; Python script.&lt;/p&gt; &lt;p&gt;I&#39;m going to assume that you have the following prerequisites:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;A Linux distribution with i3 window manager installed.&lt;/li&gt; &lt;li&gt;Python 3 installed.&lt;/li&gt; &lt;li&gt;Espanso installed and configured.&lt;/li&gt; &lt;li&gt;&lt;code&gt;ruyaml&lt;/code&gt; and &lt;code&gt;tkinter&lt;/code&gt; Python libraries installed.&lt;/li&gt; &lt;li&gt;&lt;code&gt;notify-send&lt;/code&gt; installed.&lt;/li&gt; &lt;li&gt;Basic knowledge of editing configuration files in i3.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Create a new Python script named &lt;code&gt;espansadd.py&lt;/code&gt; with the following content:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;tkinter&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;tk&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;tkinter&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;simpledialog&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;traceback&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;subprocess&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;sys&lt;/span&gt;

&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;ruyaml&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;YAML&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;ruyaml.scanner&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ScannerError&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;file_path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;expanduser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;~/.config/espanso/match/typofixer_overwrite.yml&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;append_to_yaml&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;trigger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;replace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Appends a new entry to the YAML file.&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;    Args:ath&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        file_path (str): The file to append the new entry.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        trigger (str): The trigger string to be added.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        replace (str): The replacement string to be added.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    &#34;&#34;&#34;&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;# Define the new snippet&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;new_entry&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;trigger&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;trigger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;replace&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;replace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;propagate_case&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;word&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;# Load existing data or initialize an empty list&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;expanduser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;r&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;YAML&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ScannerError&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;send_notification&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                    &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Error parsing yaml of configuration file &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file_path&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                    &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;problem_mark&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;problem&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                    &lt;span class=&#34;s2&#34;&gt;&#34;critical&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;FileNotFoundError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;send_notification&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Error opening the espanso file &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file_path&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;urgency&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;critical&#34;&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;matches&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new_entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;# Write the updated data back to the file&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;expanduser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;w+&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;yaml&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;YAML&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;yaml&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;default_flow_style&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;yaml&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dump&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;send_notification&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;urgency&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;normal&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Send a desktop notification using notify-send.&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;    Args:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        title (str): The title of the notification.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        message (str): The message body of the notification. Defaults to an empty string.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        urgency (str): The urgency level of the notification. Can be &#39;low&#39;, &#39;normal&#39;, or &#39;critical&#39;. Defaults to &#39;normal&#39;.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    &#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;notify-send&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;-u&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;urgency&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Main function to prompt user for input and append to the YAML file.&#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;# Create the main Tkinter window (it won&#39;t be shown)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;window&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tk&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Tk&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;window&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;withdraw&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# Hide the main window&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;# Prompt the user for input&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;trigger&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;simpledialog&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;askstring&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Espanso add input&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Enter trigger:&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;replace&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;simpledialog&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;askstring&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Espanso add input&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Enter replace:&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;# Check if both inputs were provided&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;trigger&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;replace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;append_to_yaml&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;trigger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;replace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;send_notification&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Espanso snippet added successfully&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;send_notification&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                &lt;span class=&#34;s2&#34;&gt;&#34;Both trigger and replace are required&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;urgency&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;critical&#34;&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;Exception&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;error_message&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;join&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;traceback&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;format_exception&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;__traceback__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;send_notification&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&#34;There was an unknown error adding the espanso entry&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;error_message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;urgency&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;critical&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;__main__&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Ensure the script has executable permissions. Run the following command:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;chmod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;+x&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;espansadd.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To make the &lt;code&gt;espansadd&lt;/code&gt; script easily accessible, we can configure a key binding in i3 to run the script. Open your i3 configuration file, typically located at &lt;code&gt;~/.config/i3/config&lt;/code&gt; or &lt;code&gt;~/.i3/config&lt;/code&gt;, and add the following lines:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;bindsym&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$mod&lt;/span&gt;+Shift+e&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--no-startup-id&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/path/to/your/espansadd.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Replace &lt;code&gt;/path/to/your/espansadd.py&lt;/code&gt; with the actual path to your script.&lt;/p&gt; &lt;p&gt;If you also want the popup windows to be in floating mode add&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;for_window&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Espanso add input&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;floating&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;enable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;After editing the configuration file, reload i3 to apply the changes. You can do this by pressing &lt;code&gt;Mod&lt;/code&gt; + &lt;code&gt;Shift&lt;/code&gt; + &lt;code&gt;R&lt;/code&gt; (where &lt;code&gt;Mod&lt;/code&gt; is typically the &lt;code&gt;Super&lt;/code&gt; or &lt;code&gt;Windows&lt;/code&gt; key) or by running the following command:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;i3-msg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reload
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Now that everything is set up, you can use the &lt;code&gt;espansadd&lt;/code&gt; script by pressing &lt;code&gt;Mod&lt;/code&gt; + &lt;code&gt;Shift&lt;/code&gt; + &lt;code&gt;E&lt;/code&gt;. This will open a dialog where you can enter the trigger and replacement text for the new Espanso snippet. After entering the information and pressing Enter, a notification will appear confirming the snippet has been added, or showing an error message if something went wrong.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;generic-coding-practices&#34;&gt;Generic Coding Practices&lt;/h3&gt; &lt;h4 id=&#34;writing-good-documentation&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/documentation/&#34;&gt;Writing good documentation&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/documentation/#references&#34;&gt;Add diátaxis as documentation writing guideline.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://diataxis.fr/&#34;&gt;Diátaxis: A systematic approach to technical documentation authoring&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;conventional-comments&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/conventional_comments/&#34;&gt;Conventional comments&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce conventional comments.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://conventionalcomments.org/&#34;&gt;Conventional comments&lt;/a&gt; is the practice to use a specific format in the review comments to express your intent and tone more clearly. It&#39;s strongly inspired by &lt;a href=&#34;https://lyz-code.github.io/blue-book/semantic_versioning/&#34;&gt;semantic versioning&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Let&#39;s take the next comment:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;This is not worded correctly.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Adding labels you can tell the difference on your intent:&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;**suggestion:** This is not worded correctly.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; Or &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;**issue (non-blocking):** This is not worded correctly.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;Labels also prompt the reviewer to give more &lt;strong&gt;actionable&lt;/strong&gt; comments.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;**suggestion:** This is not worded correctly.

Can we change this to match the wording of the marketing page?
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Labeling comments encourages collaboration and saves &lt;strong&gt;hours&lt;/strong&gt; of undercommunication and misunderstandings. They are also parseable by machines!&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Format&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Adhering to a consistent format improves reader&#39;s expectations and machine readability. Here&#39;s the format we propose: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;lt;label&amp;gt; [decorations]: &amp;lt;subject&amp;gt;

[discussion]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; - &lt;em&gt;label&lt;/em&gt; - This is a single label that signifies what kind of comment is being left. - &lt;em&gt;subject&lt;/em&gt; - This is the main message of the comment. - &lt;em&gt;decorations (optional)&lt;/em&gt; - These are extra decorating labels for the comment. They are surrounded by parentheses and comma-separated. - &lt;em&gt;discussion (optional)&lt;/em&gt; - This contains supporting statements, context, reasoning, and anything else to help communicate the &#34;why&#34; and &#34;next steps&#34; for resolving the comment. For example: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;**question (non-blocking):** At this point, does it matter which thread has won?

Maybe to prevent a race condition we should keep looping until they&#39;ve all won?
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;Can be automatically parsed into:&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;label&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;question&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;subject&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;At this point, does it matter which thread has won?&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;decorations&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;non-blocking&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;discussion&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Maybe to prevent a race condition we should keep looping until they&#39;ve all won?&#34;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;strong&gt;Labels&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;We strongly suggest using the following labels: | | | | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | &lt;strong&gt;praise:&lt;/strong&gt; | Praises highlight something positive. Try to leave at least one of these comments per review. &lt;em&gt;Do not&lt;/em&gt; leave false praise (which can actually be damaging). &lt;em&gt;Do&lt;/em&gt; look for something to sincerely praise. | | &lt;strong&gt;quibble:&lt;/strong&gt; | Quibbles are trivial preference-based requests. These should be non-blocking by nature. Similar to &lt;code&gt;polish&lt;/code&gt; but clearly preference-based.| | &lt;strong&gt;suggestion:&lt;/strong&gt; | Suggestions propose improvements to the current subject. It&#39;s important to be explicit and clear on &lt;em&gt;what&lt;/em&gt; is being suggested and &lt;em&gt;why&lt;/em&gt; it is an improvement. These are non-blocking proposals. If it&#39;s blocking use &lt;code&gt;todo&lt;/code&gt; instead.| | &lt;strong&gt;todo:&lt;/strong&gt; | TODO&#39;s are necessary changes. Distinguishing &lt;code&gt;todo&lt;/code&gt; comments from &lt;code&gt;issues&lt;/code&gt; or &lt;code&gt;suggestions&lt;/code&gt; helps direct the reader&#39;s attention to comments requiring more involvement. | | &lt;strong&gt;issue:&lt;/strong&gt; | Issues highlight specific problems with the subject under review. These problems can be user-facing or behind the scenes. It is strongly recommended to pair this comment with a &lt;code&gt;suggestion&lt;/code&gt;. If you are not sure if a problem exists or not, consider leaving a &lt;code&gt;question&lt;/code&gt;. | | &lt;strong&gt;question:&lt;/strong&gt; | Questions are appropriate if you have a potential concern but are not quite sure if it&#39;s relevant or not. Asking the author for clarification or investigation can lead to a quick resolution. | | &lt;strong&gt;thought:&lt;/strong&gt; | Thoughts represent an idea that popped up from reviewing. These comments are non-blocking by nature, but they are extremely valuable and can lead to more focused initiatives and mentoring opportunities. | | &lt;strong&gt;chore:&lt;/strong&gt; | Chores are simple tasks that must be done before the subject can be &#34;officially&#34; accepted. Usually, these comments reference some common process. Try to leave a link to the process description so that the reader knows how to resolve the chore. | | &lt;strong&gt;note:&lt;/strong&gt; | Notes are always non-blocking and simply highlight something the reader should take note of. |&lt;/p&gt; &lt;p&gt;If you like to be a bit more expressive with your labels, you may also consider:&lt;/p&gt; &lt;table&gt; &lt;thead&gt; &lt;tr&gt; &lt;th&gt;&lt;/th&gt; &lt;th&gt;&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;&lt;strong&gt;typo:&lt;/strong&gt;&lt;/td&gt; &lt;td&gt;Typo comments are like &lt;strong&gt;todo:&lt;/strong&gt;, where the main issue is a misspelling.&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;strong&gt;polish:&lt;/strong&gt;&lt;/td&gt; &lt;td&gt;Polish comments are like a &lt;strong&gt;suggestion&lt;/strong&gt;, where there is nothing necessarily wrong with the relevant content, there&#39;s just some ways to immediately improve the quality. Similar but not exactly the same as &lt;code&gt;quibble&lt;/code&gt;.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;&lt;strong&gt;Decorations&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Decorations give additional context for a comment. They help further classify comments which have the same label (for example, a security suggestion as opposed to a test suggestion). &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;**suggestion (security):** I&#39;m a bit concerned that we are implementing our own DOM purifying function here...
Could we consider using the framework instead?
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;**suggestion (test,if-minor):** It looks like we&#39;re missing some unit test coverage that the cat disappears completely.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;Decorations may be specific to each organization. If needed, we recommend establishing a minimal set of decorations (leaving room for discretion) with no ambiguity. Possible decorations include: | | | | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | &lt;strong&gt;(non-blocking)&lt;/strong&gt; | A comment with this decoration &lt;strong&gt;should not&lt;/strong&gt; prevent the subject under review from being accepted. This is helpful for organizations that consider comments blocking by default. | | &lt;strong&gt;(blocking)&lt;/strong&gt; | A comment with this decoration &lt;strong&gt;should&lt;/strong&gt; prevent the subject under review from being accepted, until it is resolved. This is helpful for organizations that consider comments non-blocking by default. | | &lt;strong&gt;(if-minor)&lt;/strong&gt; | This decoration gives some freedom to the author that they should resolve the comment only if the changes ends up being minor or trivial. |&lt;/p&gt; &lt;p&gt;Adding a decoration to a comment should improve understandability and maintain readability. Having a list of many decorations in one comment would conflict with this goal.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;More examples&lt;/strong&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;**quibble:** `little star` =&amp;gt; `little bat`

Can we update the other references as well?
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;**chore:** Let&#39;s run the `jabber-walk` CI job to make sure this doesn&#39;t break any known references.
Here are [the docs](https://en.wikipedia.org/wiki/Jabberwocky) for running this job. Feel free to reach out if you need any help!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;**praise:** Beautiful test!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Some best practices for writing helpful review feedback:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Mentoring pays off exponentially&lt;/li&gt; &lt;li&gt;Leave actionable comments&lt;/li&gt; &lt;li&gt;Combine similar comments&lt;/li&gt; &lt;li&gt;Replace &#34;you&#34; with &#34;we&#34;&lt;/li&gt; &lt;li&gt;Replace &#34;should&#34; with &#34;could&#34;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt; - &lt;a href=&#34;https://conventionalcomments.org/&#34;&gt;Home&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;ocr&#34;&gt;OCR&lt;/h3&gt; &lt;h4 id=&#34;camelot&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/camelot/&#34;&gt;Camelot&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Camelot.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://camelot-py.readthedocs.io/en/master/&#34;&gt;Camelot&lt;/a&gt; is a Python library that can help you extract tables from PDFs&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;camelot&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;tables&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;camelot&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read_pdf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;foo.pdf&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;tables&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TableList&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;tables&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;foo.csv&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;csv&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;compress&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# json, excel, html, markdown, sqlite&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;tables&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Table&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;shape&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;tables&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parsing_report&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s1&#34;&gt;&#39;accuracy&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;99.02&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;s1&#34;&gt;&#39;whitespace&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;12.24&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;s1&#34;&gt;&#39;order&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;s1&#34;&gt;&#39;page&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;tables&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;to_csv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;foo.csv&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# to_json, to_excel, to_html, to_markdown, to_sqlite&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;tables&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;df&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# get a pandas DataFrame!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://camelot-py.readthedocs.io/en/master/user/install.html#install&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To install Camelot from PyPI using pip, please include the extra cv requirement as shown:&lt;/p&gt; &lt;p&gt;$ pip install &#34;camelot-py[base]&#34;&lt;/p&gt; &lt;p&gt;It requires Ghostscript to be able to use the &lt;code&gt;lattice&lt;/code&gt; mode. Which is better than using &lt;code&gt;tabular-py&lt;/code&gt; that requires java to be installed.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://camelot-py.readthedocs.io/en/master/user/advanced.html#process-background-lines&#34;&gt;Process background lines&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To detect line segments, Lattice needs the lines that make the table to be in the foreground. To process background lines, you can pass process_background=True.&lt;/p&gt; &lt;p&gt;tables = camelot.read_pdf(&#39;background_lines.pdf&#39;, process_background=True)&lt;/p&gt; &lt;p&gt;tables[1].df&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt; - &lt;a href=&#34;https://camelot-py.readthedocs.io/en/master/index.html&#34;&gt;Docs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;devsecops&#34;&gt;DevSecOps&lt;/h2&gt; &lt;h3 id=&#34;infrastructure-as-code&#34;&gt;Infrastructure as Code&lt;/h3&gt; &lt;h4 id=&#34;ansible-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/&#34;&gt;Ansible Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#fix-the-error-become-is-not-a-valid-attribute-for-a-includerole-error&#34;&gt;Fix the &lt;code&gt;ERROR! &#39;become&#39; is not a valid attribute for a IncludeRole&lt;/code&gt; error.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you&#39;re trying to do something like: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;tasks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;Install&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;nfs&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;become&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ansible.builtin.include_role&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;nfs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;You need to use this other syntax:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;tasks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;Install&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;nfs&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ansible.builtin.include_role&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;nfs&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;apply&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;become&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#set-host-variables-using-a-dynamic-inventory&#34;&gt;Set host variables using a dynamic inventory.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;As with a normal inventory you can use the &lt;code&gt;host_vars&lt;/code&gt; files with the proper name.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#avoid-arbitrary-disk-mount&#34;&gt;Avoid arbitrary disk mount.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Instead of using &lt;code&gt;/dev/sda&lt;/code&gt; use &lt;code&gt;/dev/disk/by-id/whatever&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#get-the-user-running-ansible-in-the-host-&#34;&gt;Get the user running ansible in the host.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you &lt;code&gt;gather_facts&lt;/code&gt; use the &lt;code&gt;ansible_user_id&lt;/code&gt; variable.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#filter-json-data&#34;&gt;Filter json data.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To select a single element or a data subset from a complex data structure in JSON format (for example, Ansible facts), use the &lt;code&gt;community.general.json_query&lt;/code&gt; filter. The &lt;code&gt;community.general.json_query&lt;/code&gt; filter lets you query a complex JSON structure and iterate over it using a loop structure.&lt;/p&gt; &lt;p&gt;This filter is built upon jmespath, and you can use the same syntax. For examples, see &lt;a href=&#34;http://jmespath.org/examples.html&#34;&gt;jmespath examples&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;A complex example would be:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;ec2_facts&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;json_query(&#39;instances[0].block_device_mappings[?device_name!=`/dev/sda1`&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;device_name!=`/dev/xvda`].{device_name:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;device_name,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;id:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;ebs.volume_id}&#39;)&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This snippet:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Gets all dictionaries under the block_device_mappings list which &lt;code&gt;device_name&lt;/code&gt; is not equal to &lt;code&gt;/dev/sda1&lt;/code&gt; or &lt;code&gt;/dev/xvda&lt;/code&gt;&lt;/li&gt; &lt;li&gt;From those results it extracts and flattens only the desired values. In this case &lt;code&gt;device_name&lt;/code&gt; and the &lt;code&gt;id&lt;/code&gt; which is at the key &lt;code&gt;ebs.volume_id&lt;/code&gt; of each of the items of the block_device_mappings list.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#do-asserts&#34;&gt;Do asserts.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;After version 2.7 both &#39;msg&#39; and &#39;fail_msg&#39; can customize failing assertion message&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ansible.builtin.assert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;that&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;my_param &amp;lt;= 100&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;my_param &amp;gt;= 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;fail_msg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;&#39;my_param&#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;must&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;be&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;between&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;and&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;100&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;success_msg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;&#39;my_param&#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;between&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;and&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;100&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#split-a-variable-in-ansible-&#34;&gt;Split a variable in ansible.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;item | split (&#39;@&#39;) | last&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#get-a-list-of-ec2-volumes-mounted-on-an-instance-an-their-mount-points&#34;&gt;Get a list of EC2 volumes mounted on an instance an their mount points.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Assuming that each volume has a tag &lt;code&gt;mount_point&lt;/code&gt; you could:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Gather EC2 instance metadata facts&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;amazon.aws.ec2_metadata_facts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;

&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Gather info on the mounted disks&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;delegate_to&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;localhost&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;block&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Gather information about the instance&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;amazon.aws.ec2_instance_info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;instance_ids&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;ansible_ec2_instance_id&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;register&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ec2_facts&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Gather volume tags&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;amazon.aws.ec2_vol_info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;filters&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volume-id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;item.id&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# We exclude the root disk as they are already mounted and formatted&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;loop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;ec2_facts&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;json_query(&#39;instances[0].block_device_mappings[?device_name!=`/dev/sda1`&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;device_name!=`/dev/xvda`].{device_name:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;device_name,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;id:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;ebs.volume_id}&#39;)&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;register&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;volume_tags_data&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Save the required volume data&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;set_fact&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;volume_tags_data&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;json_query(&#39;results[0].volumes[].{id:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;id,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;mount_point:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;tags.mount_point}&#39;)&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Display volumes data&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;debug&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Make sure that all volumes have a mount point&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;assert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;that&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;item.mount_point is defined&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;item.mount_point|length &amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;fail_msg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;Configure&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;the&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;mount_point&#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;tag&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;the&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;volume&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;item.id&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;the&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;ansible_ec2_instance_id&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;success_msg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;volume&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;item.id&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;has&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;the&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;mount_point&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;tag&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;well&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;set&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;loop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#create-a-list-of-dictionaries-using-ansible&#34;&gt;Create a list of dictionaries using ansible.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Create and Add items to dictionary&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;set_fact&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;userdata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;userdata&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;default({})&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;combine&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;({&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;item.key&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;item.value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;})&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;with_items&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;key&#39;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;Name&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;value&#39;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;SaravAK&#39;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;key&#39;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;Email&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;value&#39;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;sarav@gritfy.com&#39;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;key&#39;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;Location&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;value&#39;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;Coimbatore&#39;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;key&#39;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;Nationality&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;value&#39;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;Indian&#39;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#merge-two-dictionaries-on-a-key-&#34;&gt;Merge two dictionaries on a key.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you have these two lists:&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;s&#34;&gt;&#34;list1&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;a&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;b&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;c&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;d&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;a&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;e&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;c&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;f&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;

&lt;span class=&#34;s&#34;&gt;&#34;list2&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;a&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;e&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;g&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;h&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;a&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;b&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;g&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;i&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; And want to merge them using the value of key &#34;a&#34;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;s&#34;&gt;&#34;list3&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;a&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;b&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;c&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;d&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;g&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;i&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;a&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;e&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;c&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;f&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;g&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;h&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you can install the collection community.general use the filter lists_mergeby. The expression below gives the same result&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;list3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;list1|community.general.lists_mergeby(list2,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;a&#39;)&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#loop-over-dict-fails-when-only-one-element-detected&#34;&gt;Loop over dict fails when only one element detected.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you see the &lt;code&gt;If you passed a list/dict of just one element, try adding wantlist=True to your lookup invocation or use q/query instead of lookup.&#34;&lt;/code&gt; error in an Ansible log it means that the content of the variable is not the type you expect it to be. This can happen for example for lists that have only one or zero elements, which gets translated into a string thus breaking the &lt;code&gt;loop&lt;/code&gt; structure.&lt;/p&gt; &lt;p&gt;So instead of: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Create filesystem on device&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;community.general.filesystem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;fstype&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ext4&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;dev&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;/dev/disk/by-id/nvme-Amazon_Elastic_Block_Store_vol{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;item.id&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;split(&#39;-&#39;)&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;last&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;loop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;You can use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Create filesystem on device&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;community.general.filesystem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;fstype&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ext4&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;dev&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;/dev/disk/by-id/nvme-Amazon_Elastic_Block_Store_vol{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;item.id&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;split(&#39;-&#39;)&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;last&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;loop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;lookup(&#39;list&#39;,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;volumes,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;wantlist=True)&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If that gives you issues you can use this other construction instead:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Save the required volume data&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;set_fact&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;volume_tags_data&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;json_query(&#39;results[0].volumes[].{id:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;id,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;mount_point:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;tags.mount_point}&#39;)&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Get result type for the volumes&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;set_fact&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volumes_type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;type_debug&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Display volumes type&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;debug&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;volumes_type&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Force list of volumes if it&#39;s a string&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;set_fact&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;when&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;volumes_type == &#39;str&#39;&lt;/span&gt;

&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Force list of volumes if it&#39;s a dictionary&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;set_fact&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;[volumes]&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;when&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;volumes_type == &#39;dict&#39;&lt;/span&gt;

&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Create filesystem on device&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;community.general.filesystem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;fstype&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ext4&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;dev&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;/dev/disk/by-id/nvme-Amazon_Elastic_Block_Store_vol{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;item.id&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;split(&#39;-&#39;)&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;last&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;loop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#set-the-ssh-connection-port-using-dynamic-inventories&#34;&gt;Set the ssh connection port using dynamic inventories.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To specify a custom SSH port, you can use a &lt;code&gt;host_vars&lt;/code&gt; or &lt;code&gt;group_vars&lt;/code&gt; file. For example, create a &lt;code&gt;group_vars&lt;/code&gt; directory and a file named &lt;code&gt;all.yaml&lt;/code&gt; inside it:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;ansible_port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;2222&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;infrastructure-solutions&#34;&gt;Infrastructure Solutions&lt;/h3&gt; &lt;h4 id=&#34;kubernetes&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes/&#34;&gt;Kubernetes&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce IceKube.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://twitter.com/clintgibler/status/1732459956669214784&#34;&gt;IceKube&lt;/a&gt; tool for finding complex attack paths in Kubernetes clusters. It&#39;s like Bloodhound for Kubernetes. It uses Neo4j to store &amp;amp; analyze Kubernetes resource relationships → identify attack paths &amp;amp; security misconfigs&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes/#tools-to-test&#34;&gt;Add reloader to tools to test.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/stakater/Reloader&#34;&gt;stakater/reloader&lt;/a&gt;: A Kubernetes controller to watch changes in ConfigMap and Secrets and do rolling upgrades on Pods with their associated Deployment, StatefulSet, DaemonSet and DeploymentConfig. Useful for not that clever applications that need a reboot when a configmap changes.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;aws&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/aws/aws/&#34;&gt;AWS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/aws/aws/#get-the-role-used-by-the-instance&#34;&gt;Get the role used by the instance.&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;kubectl-commands&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aws_savings_plan/&#34;&gt;Kubectl Commands&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/aws_savings_plan/#understanding-how-reserved-instances-are-applied&#34;&gt;Understanding how reserved instances are applied.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;A Reserved Instance that is purchased for a Region is called a regional Reserved Instance, and provides Availability Zone and instance size flexibility.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The Reserved Instance discount applies to instance usage in any Availability Zone in that Region.&lt;/li&gt; &lt;li&gt;The Reserved Instance discount applies to instance usage within the instance family, regardless of size—this is known as instance size flexibility.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;With instance size flexibility, the Reserved Instance discount applies to instance usage for instances that have the same family, generation, and attribute. The Reserved Instance is applied from the smallest to the largest instance size within the instance family based on the normalization factor.&lt;/p&gt; &lt;p&gt;The discount applies either fully or partially to running instances of the same instance family, depending on the instance size of the reservation, in any Availability Zone in the Region. The only attributes that must be matched are the instance family, tenancy, and platform.&lt;/p&gt; &lt;p&gt;The following table lists the different sizes within an instance family, and the corresponding normalization factor. This scale is used to apply the discounted rate of Reserved Instances to the normalized usage of the instance family.&lt;/p&gt; &lt;table&gt; &lt;thead&gt; &lt;tr&gt; &lt;th&gt;Instance size&lt;/th&gt; &lt;th&gt;Normalization factor&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;nano&lt;/td&gt; &lt;td&gt;0.25&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;micro&lt;/td&gt; &lt;td&gt;0.5&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;small&lt;/td&gt; &lt;td&gt;1&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;medium&lt;/td&gt; &lt;td&gt;2&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;large&lt;/td&gt; &lt;td&gt;4&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;xlarge&lt;/td&gt; &lt;td&gt;8&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;2xlarge&lt;/td&gt; &lt;td&gt;16&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;3xlarge&lt;/td&gt; &lt;td&gt;24&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;4xlarge&lt;/td&gt; &lt;td&gt;32&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;6xlarge&lt;/td&gt; &lt;td&gt;48&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;8xlarge&lt;/td&gt; &lt;td&gt;64&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;9xlarge&lt;/td&gt; &lt;td&gt;72&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;10xlarge&lt;/td&gt; &lt;td&gt;80&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;12xlarge&lt;/td&gt; &lt;td&gt;96&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;16xlarge&lt;/td&gt; &lt;td&gt;128&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;18xlarge&lt;/td&gt; &lt;td&gt;144&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;24xlarge&lt;/td&gt; &lt;td&gt;192&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;32xlarge&lt;/td&gt; &lt;td&gt;256&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;48xlarge&lt;/td&gt; &lt;td&gt;384&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;56xlarge&lt;/td&gt; &lt;td&gt;448&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;112xlarge&lt;/td&gt; &lt;td&gt;896&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;For example, a &lt;code&gt;t2.medium&lt;/code&gt; instance has a normalization factor of &lt;code&gt;2&lt;/code&gt;. If you purchase a &lt;code&gt;t2.medium&lt;/code&gt; default tenancy Amazon Linux/Unix Reserved Instance in the US East (N. Virginia) and you have two running &lt;code&gt;t2.small&lt;/code&gt; instances in your account in that Region, the billing benefit is applied in full to both instances.&lt;/p&gt; &lt;p&gt;Or, if you have one &lt;code&gt;t2.large&lt;/code&gt; instance running in your account in the US East (N. Virginia) Region, the billing benefit is applied to 50% of the usage of the instance.&lt;/p&gt; &lt;p&gt;Limitations:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;em&gt;Supported&lt;/em&gt;: Instance size flexibility is only supported for Regional Reserved Instances.&lt;/li&gt; &lt;li&gt;&lt;em&gt;Not supported&lt;/em&gt;: Instance size flexibility is not supported for the following Reserved Instances:&lt;ul&gt; &lt;li&gt;Reserved Instances that are purchased for a specific Availability Zone (zonal Reserved Instances)&lt;/li&gt; &lt;li&gt;Reserved Instances for G4ad, G4dn, G5, G5g, and Inf1 instances&lt;/li&gt; &lt;li&gt;Reserved Instances for Windows Server, Windows Server with SQL Standard, Windows Server with SQL Server Enterprise, Windows Server with SQL Server Web, RHEL, and SUSE Linux Enterprise Server&lt;/li&gt; &lt;li&gt;Reserved Instances with dedicated tenancy&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/aws_savings_plan/#ec2-instance-savings-plan-versus-reserved-instances&#34;&gt;EC2 Instance savings plan versus reserved instances.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I&#39;ve been comparing the EC2 Reserved Instances and of the EC2 instance family savings plans and decided to go with the second because:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;They both have almost the same rates. Reserved instances round the price at the 3&lt;sup&gt;rd&lt;/sup&gt; decimal and the savings plan at the fourth, but this difference is neglegible.&lt;/li&gt; &lt;li&gt;Savings plan are easier to calculate, as you just need to multiply the number of instances you want times the current rate and add them all up.&lt;/li&gt; &lt;li&gt;Easier to understand: To reserve instances you need to take into account the instance flexibility and the normalization factors which makes it difficult both to make the plans and also to audit how well you&#39;re using it.&lt;/li&gt; &lt;li&gt;Easier to audit: In addition to the above point, you have nice dashboards to see the coverage and utilization over time of your ec2 instance savings plans, which are at the same place as the other savings plans.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/aws_savings_plan/#doing-your-savings-plan&#34;&gt;Important notes when doing a savings plan.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Always use the reservation rates instead of the on-demand rates!&lt;/li&gt; &lt;li&gt;Analyze your coverage reports. You don&#39;t want to have many points of 100% coverage as it means that you&#39;re using less resources than you&#39;ve reserved. On the other hand it&#39;s fine to sometimes use less resources than the reserved if that will mean a greater overall savings. It&#39;s a tight balance.&lt;/li&gt; &lt;li&gt;The Savings plan reservation is taken into account at hour level, not at month or year level. That means that if you reserve 1&lt;span class=&#34;arithmatex&#34;&gt;&lt;span class=&#34;MathJax_Preview&#34;&gt;/hour of an instance type and you use for example 2&lt;/span&gt;&lt;script type=&#34;math/tex&#34;&gt;/hour of an instance type and you use for example 2&lt;/script&gt;&lt;/span&gt;/hour half the day and 0&lt;span class=&#34;arithmatex&#34;&gt;&lt;span class=&#34;MathJax_Preview&#34;&gt;/hour half the day, you&#39;ll have a 100% coverage of your plan the first hour and another 1&lt;/span&gt;&lt;script type=&#34;math/tex&#34;&gt;/hour half the day, you&#39;ll have a 100% coverage of your plan the first hour and another 1&lt;/script&gt;&lt;/span&gt;/hour of on-demand infrastructure cost for the first part of the day. On the second part of the day you&#39;ll have a 0% coverage. This means that you should only reserve the amount of resources you plan to be using 100% of the time throughout your savings plan. Again you may want to overcommit a little bit, reducing the utilization percentage of a plan but getting better savings in the end.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubectl/kubectl_commands/#upload-a-file-to-a-pod&#34;&gt;Upload a file to a pod.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;path_to_local_file&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;container_id&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;:&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;path_to_file&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubectl/kubectl_commands/#delete-pods-that-are-stuck-in-terminating-state-for-a-while&#34;&gt;Delete pods that are stuck in terminating state for a while.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;delete&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;pod-name&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--grace-period&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--force
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;volumes&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/efs/&#34;&gt;Volumes&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Troubleshoot don&#39;t have enough permissions to start restore from backup.&lt;/p&gt; &lt;p&gt;That may be because the default EFS backup policy doesn&#39;t let you do that (stupid, I know).&lt;/p&gt; &lt;p&gt;To fix it go into the backup policy and remove the next line from the &lt;code&gt;Deny&lt;/code&gt; policy:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;err&#34;&gt;backup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;S&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;tart&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;Res&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;oreJob&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes_volumes/#specify-a-path-of-a-configmap&#34;&gt;Specify a path of a configmap.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you have a configmap with a key &lt;code&gt;ssh-known-hosts&lt;/code&gt; and you want to mount it&#39;s content in a file, in the deployment &lt;code&gt;volumeMounts&lt;/code&gt; section you can use the &lt;code&gt;subPath&lt;/code&gt; field:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;mountPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/home/argocd/.ssh/known_hosts&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ssh-known-hosts&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;subPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ssh_known_hosts&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;readOnly&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/efs/#list-the-size-of-the-recovery-points&#34;&gt;List the size of the recovery points.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;BACKUP_VAULT_NAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;your-vault-name&#34;&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;RECOVERY_POINTS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;aws&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;backup&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list-recovery-points-by-backup-vault&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--backup-vault-name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$BACKUP_VAULT_NAME&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--query&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;RecoveryPoints[*].[RecoveryPointArn,BackupSizeInBytes,CreationDate]&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--output&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;text&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-e&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Creation Date\t\tRecovery Point ARN\t\t\t\t\t\t\t\t\tSize (TB)&#34;&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;---------------------------------------------------------------------------------------------------------------------&#34;&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;RECOVERY_POINT_ARN&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;BACKUP_SIZE_BYTES&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;CREATION_DATE&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Remove the decimal part from the epoch time&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;EPOCH_TIME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$CREATION_DATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cut&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;s1&#34;&gt;&#39;.&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f1&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Convert the creation date from epoch time to YYYY-MM-DD format&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;FORMATTED_DATE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;date&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;@&lt;span class=&#34;nv&#34;&gt;$EPOCH_TIME&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;+&lt;span class=&#34;s2&#34;&gt;&#34;%Y-%m-%d&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;SIZE_TB&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;scale=6; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$BACKUP_SIZE_BYTES&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; / (1024^4)&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;bc&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# echo -e &#34;$FORMATTED_DATE\t$RECOVERY_POINT_ARN\t$SIZE_TB&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;%-16s %-80s %10.6f\n&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$FORMATTED_DATE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$RECOVERY_POINT_ARN&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$SIZE_TB&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$RECOVERY_POINTS&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/efs/#list-the-size-of-the-jobs&#34;&gt;List the size of the jobs.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To list AWS Backup jobs and display their completion dates and sizes in a human-readable format, you can use the following AWS CLI command combined with &lt;code&gt;jq&lt;/code&gt; for parsing and formatting the output. This command handles cases where the backup size might be null and rounds the size to the nearest whole number in gigabytes.&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;aws&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;backup&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list-backup-jobs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--output&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;json&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;jq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;  .BackupJobs[] |&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;  [&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;    (.CompletionDate | strftime(&#34;%Y-%m-%d %H:%M:%S&#34;)),&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;    (if .BackupSizeInBytes == null then &#34;0GB&#34; else ((.BackupSizeInBytes / 1024 / 1024 / 1024) | floor | tostring + &#34; GB&#34;) end)&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;  ] |&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;  @tsv&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;column&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;s1&#34;&gt;$&#39;\t&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; Explanation:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;aws backup list-backup-jobs --output json&lt;/code&gt;: Lists all AWS Backup jobs in JSON format.&lt;/li&gt; &lt;li&gt;&lt;code&gt;.BackupJobs[]&lt;/code&gt;: Iterates over each backup job.&lt;/li&gt; &lt;li&gt;&lt;code&gt;(.CompletionDate | strftime(&#34;%Y-%m-%d %H:%M:%S&#34;))&lt;/code&gt;: Converts the Unix timestamp in CompletionDate to a human-readable date format (YYYY-MM-DD HH:MM:SS).&lt;/li&gt; &lt;li&gt;&lt;code&gt;(if .BackupSizeInBytes == null then &#34;0GB&#34; else ((.BackupSizeInBytes / 1024 / 1024 / 1024) | floor | tostring + &#34; GB&#34;) end)&lt;/code&gt;: Checks if BackupSizeInBytes is null. If it is, outputs &#34;0GB&#34;. Otherwise, converts the size from bytes to gigabytes, rounds it down to the nearest whole number, and appends &#34; GB&#34;.&lt;/li&gt; &lt;li&gt;&lt;code&gt;| @tsv&lt;/code&gt;: Formats the output as tab-separated values.&lt;/li&gt; &lt;li&gt;&lt;code&gt;column -t -s$&#39;\t&#39;&lt;/code&gt;: Formats the TSV output into a table with columns aligned.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;continuous-deployment&#34;&gt;Continuous Deployment&lt;/h3&gt; &lt;h4 id=&#34;argocd&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/argocd/&#34;&gt;ArgoCD&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/argocd/#not-there-yet&#34;&gt;Not there yet.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/argoproj/argo-cd/issues/18798&#34;&gt;Support git webhook on Applicationsets for gitea/forgejo&lt;/a&gt;: although you could use an ugly fix adding &lt;code&gt;spec.generators[i].requeueAfterSeconds&lt;/code&gt; to change the interval that ArgoCD uses to refresh the repositories, which is 3 minutes by default.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;continuous-integration&#34;&gt;Continuous Integration&lt;/h3&gt; &lt;h4 id=&#34;bandit&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/bandit/&#34;&gt;Bandit&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/bandit/#b603:-subprocess_without_shell_equals_true&#34;&gt;Solving warning B603: subprocess_without_shell_equals_true.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The &lt;code&gt;B603: subprocess_without_shell_equals_true&lt;/code&gt; issue in Bandit is raised when the &lt;code&gt;subprocess&lt;/code&gt; module is used without setting &lt;code&gt;shell=True&lt;/code&gt;. Bandit flags this because using &lt;code&gt;shell=True&lt;/code&gt; can be a security risk if the command includes user-supplied input, as it opens the door to shell injection attacks.&lt;/p&gt; &lt;p&gt;To fix it:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Avoid &lt;code&gt;shell=True&lt;/code&gt; if possible: Instead, pass the command and its arguments as a list to &lt;code&gt;subprocess.Popen&lt;/code&gt; (or &lt;code&gt;subprocess.run&lt;/code&gt;, &lt;code&gt;subprocess.call&lt;/code&gt;, etc.). This way, the command is executed directly without invoking the shell, reducing the risk of injection attacks.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;Here&#39;s an example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;subprocess&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;# Instead of this:&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;# subprocess.Popen(&#34;ls -l&#34;, shell=True)&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;# Do this:&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Popen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;ls&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;-l&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt;When you must use &lt;code&gt;shell=True&lt;/code&gt;: - If you absolutely need to use &lt;code&gt;shell=True&lt;/code&gt; (e.g., because you are running a complex shell command or using shell features like wildcards), ensure that the command is either hardcoded or sanitized to avoid security risks.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;Example with &lt;code&gt;shell=True&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;subprocess&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;# Command is hardcoded and safe&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;command&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;ls -l | grep py&#34;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Popen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;shell&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If the command includes user input, sanitize the input carefully:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;subprocess&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;user_input&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;some_directory&#34;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;command&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;ls -l &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;list2cmdline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Popen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;shell&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Even with precautions, using &lt;code&gt;shell=True&lt;/code&gt; is risky with user input, so avoid it if possible.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Explicitly tell bandit you have considered the risk: If you have reviewed the code and are confident that the code is safe in your particular case, you can mark the line with a &lt;code&gt;# nosec&lt;/code&gt; comment to tell Bandit to ignore the issue:&lt;/li&gt; &lt;/ol&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;subprocess&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;command&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;ls -l | grep py&#34;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Popen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;shell&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# nosec&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;safety&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/safety/&#34;&gt;Safety&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add deprecation warning.&lt;/p&gt; &lt;p&gt;Since 2024-05-27 it requires an account to work, use &lt;a href=&#34;https://lyz-code.github.io/blue-book/pip_audit/&#34;&gt;pip-audit&lt;/a&gt; instead.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;security-checkers&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/pip_audit/&#34;&gt;Security Checkers&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce pip-audit.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/pypa/pip-audit&#34;&gt;&lt;code&gt;pip-audit&lt;/code&gt;&lt;/a&gt; is the official pypa tool for scanning Python environments for packages with known vulnerabilities. It uses the Python Packaging Advisory Database (&lt;a href=&#34;https://github.com/pypa/advisory-database&#34;&gt;https://github.com/pypa/advisory-database&lt;/a&gt;) via the PyPI JSON API as a source of vulnerability reports.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pip-audit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip-audit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; On completion, pip-audit will exit with a code indicating its status.&lt;/p&gt; &lt;p&gt;The current codes are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;0&lt;/code&gt;: No known vulnerabilities were detected.&lt;/li&gt; &lt;li&gt;&lt;code&gt;1&lt;/code&gt;: One or more known vulnerabilities were found.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;pip-audit&#39;s exit code cannot be suppressed. See &lt;a href=&#34;https://github.com/pypa/pip-audit?tab=readme-ov-file#suppressing-exit-codes-from-pip-audit&#34;&gt;Suppressing exit codes from pip-audit&lt;/a&gt; for supported alternatives.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/pypa/pip-audit&#34;&gt;Code&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;yamllint&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/yamllint/&#34;&gt;Yamllint&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/yamllint/#ignore-certain-files&#34;&gt;Ignore certain files.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It is possible to exclude specific files or directories, so that the linter doesn’t process them. They can be provided either as a list of paths, or as a bulk string.&lt;/p&gt; &lt;p&gt;You can either totally ignore files (they won’t be looked at):&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;extends&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;default&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;ignore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;/this/specific/file.yaml&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;all/this/directory/&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;*.template.yaml&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;ignore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/this/specific/file.yaml&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;all/this/directory/&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;*.template.yaml&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;automating-processes&#34;&gt;Automating Processes&lt;/h3&gt; &lt;h4 id=&#34;letsencrypt&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/letsencrypt/&#34;&gt;letsencrypt&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/letsencrypt/#manually-renew-a-certificate&#34;&gt;Manually renew a certificate.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Linuxserver swag container renews the certificates at night. If you don&#39;t have your server up at those hours your certificate won&#39;t be renewed automatically and you need to react to the prometheus alert manually. To do so get into the container and run &lt;code&gt;certbot renew&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;storage&#34;&gt;Storage&lt;/h3&gt; &lt;h4 id=&#34;nas&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/nas/&#34;&gt;NAS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Add suggestions when buying a motherboard.&lt;/p&gt; &lt;p&gt;When choosing a motherboard make sure that:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;If you want &lt;a href=&#34;https://lyz-code.github.io/blue-book/ecc/&#34;&gt;ECC&lt;/a&gt; that it &lt;a href=&#34;https://lyz-code.github.io/blue-book/ecc/#confusion-on-boards-supporting-ecc&#34;&gt;truly supports ECC&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/watchdog/#watchdog-hardware is-disabled-error-on-boot&#34;&gt;It is IPMI compliant, if you want to have hardware watchdog support&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;openzfs&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/&#34;&gt;OpenZFS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Solve the pool or dataset is busy error.&lt;/p&gt; &lt;p&gt;If you get an error of &lt;code&gt;pool or dataset is busy&lt;/code&gt; run the next command to see which process is still running on the pool:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;lsof&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dataset-name
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#monitorization&#34;&gt;Monitor dbgmsg with loki.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you use &lt;a href=&#34;https://lyz-code.github.io/blue-book/loki/&#34;&gt;loki&lt;/a&gt; remember to monitor the &lt;code&gt;/proc/spl/kstat/zfs/dbgmsg&lt;/code&gt; file:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;job_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;zfs&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;static_configs&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;targets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;localhost&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;job&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;zfs&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;__path__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/proc/spl/kstat/zfs/dbgmsg&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Add loki alerts on the kernel panic error.&lt;/p&gt; &lt;p&gt;You can monitor this issue with loki using the next alerts:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;groups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;zfs&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;SlowSpaSyncZFSError&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;w w-Error&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;count_over_time({job=&#34;zfs&#34;} |~ `spa_deadman.*slow spa_sync` [5m])&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;1m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;critical&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;Slow&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;sync&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;traces&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;found&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;the&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;ZFS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;debug&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;logs&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;at&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;This&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;usually&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;happens&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;before&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;the&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;ZFS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;becomes&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;unresponsible&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/sanoid/#monitorization&#34;&gt;Monitorization.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can monitor this issue with loki using the next alerts:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;groups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;zfs&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ErrorInSanoidLogs&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;count_over_time({job=&#34;systemd-journal&#34;, syslog_identifier=&#34;sanoid&#34;} |= `ERROR` [5m])&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;1m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;critical&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;Errors&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;found&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;sanoid&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;at&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#set-zfs-module-parameters-or-options&#34;&gt;Set zfs module parameters or options.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Most of the ZFS kernel module parameters are accessible in the SysFS &lt;code&gt;/sys/module/zfs/parameters&lt;/code&gt; directory. Current values can be observed by&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/sys/module/zfs/parameters/PARAMETER
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Many of these can be changed by writing new values. These are denoted by Change|Dynamic in the PARAMETER details below.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;NEWVALUE&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/sys/module/zfs/parameters/PARAMETER
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If the parameter is not dynamically adjustable, an error can occur and the value will not be set. It can be helpful to check the permissions for the &lt;code&gt;PARAMETER&lt;/code&gt; file in SysFS.&lt;/p&gt; &lt;p&gt;In some cases, the parameter must be set prior to loading the kernel modules or it is desired to have the parameters set automatically at boot time. For many distros, this can be accomplished by creating a file named &lt;code&gt;/etc/modprobe.d/zfs.conf&lt;/code&gt; containing a text line for each module parameter using the format:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;options&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;PARAMETER&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;VALUE
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Some parameters related to ZFS operations are located in module parameters other than in the zfs kernel module. These are documented in the individual parameter description. Unless otherwise noted, the tunable applies to the zfs kernel module. For example, the &lt;code&gt;icp&lt;/code&gt; kernel module parameters are visible in the &lt;code&gt;/sys/module/icp/parameters&lt;/code&gt; directory and can be set by default at boot time by changing the &lt;code&gt;/etc/modprobe.d/icp.conf&lt;/code&gt; file.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#configure-the-deadman-failsafe-measure&#34;&gt;Configure the deadman failsafe measure.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;ZFS has a safety measure called the &lt;a href=&#34;https://openzfs.github.io/openzfs-docs/man/master/4/zfs.4.html#zfs_deadman_enabled&#34;&gt;zfs_deadman_failmode&lt;/a&gt;. When a pool sync operation takes longer than &lt;code&gt;zfs_deadman_synctime_ms&lt;/code&gt;, or when an individual I/O operation takes longer than &lt;code&gt;zfs_deadman_ziotime_ms&lt;/code&gt;, then the operation is considered to be &#34;hung&#34;. If &lt;code&gt;zfs_deadman_enabled&lt;/code&gt; is set, then the deadman behavior is invoked as described by &lt;code&gt;zfs_deadman_failmode&lt;/code&gt;. By default, the deadman is enabled and set to wait which results in &#34;hung&#34; I/O operations only being logged. The deadman is automatically disabled when a pool gets suspended.&lt;/p&gt; &lt;p&gt;&lt;code&gt;zfs_deadman_failmode&lt;/code&gt; configuration can have the next values:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;wait&lt;/code&gt;: Wait for a &#34;hung&#34; operation to complete. For each &#34;hung&#34; operation a &#34;deadman&#34; event will be posted describing that operation.&lt;/li&gt; &lt;li&gt;&lt;code&gt;continue&lt;/code&gt;: Attempt to recover from a &#34;hung&#34; operation by re-dispatching it to the I/O pipeline if possible.&lt;/li&gt; &lt;li&gt;&lt;code&gt;panic&lt;/code&gt;: Panic the system. This can be used to facilitate automatic fail-over to a properly configured fail-over partner.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Follow the guides under &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#set-zfs-module-parameters-or-options&#34;&gt;Set zfs module parameters or options&lt;/a&gt; to change this value.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#monitor-the-zfs-events&#34;&gt;Monitor the ZFS events.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can see the ZFS events using &lt;code&gt;zpool events -v&lt;/code&gt;. If you want to be alerted on these events you can use &lt;a href=&#34;https://codeberg.org/lyz/zfs_events&#34;&gt;this service&lt;/a&gt; to ingest them into Loki and raise alerts.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#manually-create-a-backup&#34;&gt;Manually create a backup.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To create a snapshot of &lt;code&gt;tank/home/ahrens&lt;/code&gt; that is named &lt;code&gt;friday&lt;/code&gt; run:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;snapshot&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank/home/ahrens@friday
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Tweak loki alerts.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;SyncoidCorruptedSnapshotSendError&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;count_over_time({syslog_identifier=&#34;syncoid_send_backups&#34;} |= `cannot receive incremental stream: invalid backup stream` [15m]) &amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;critical&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;Error&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;trying&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;to&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;send&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;corrupted&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;snapshot&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;at&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;Look&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;at&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;the&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;loki&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;to&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;identify&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;the&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;snapshot&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;question.&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Delete&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;it&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;and&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;then&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;the&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;sync&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;again&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;SanoidNotRunningError&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;sum by (hostname) (count_over_time({job=&#34;systemd-journal&#34;, syslog_identifier=&#34;sanoid&#34;}[1h])) or sum by (hostname) (count_over_time({job=&#34;systemd-journal&#34;}[1h]) * 0)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;critical&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;Sanoid&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;has&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;not&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;shown&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;signs&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;to&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;be&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;alive&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;the&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;last&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;hour&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;at&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;least&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;arva&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;and&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;helm&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;SlowSpaSyncZFSError&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;count_over_time({job=&#34;zfs&#34;} |~ `spa_deadman.*slow spa_sync` [10m]) &amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;critical&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;Slow&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;sync&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;traces&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;found&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;the&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;ZFS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;debug&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;logs&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;at&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;This&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;usually&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;happens&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;before&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;the&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;ZFS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;becomes&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;unresponsible&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The &lt;code&gt;SanoidNotRunningError&lt;/code&gt; alert uses a broader search that ensures that all hosts are included and multiplies it to 0 to raise the alert if none is shown for the &lt;code&gt;sanoid&lt;/code&gt; service.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#sync-an-already-created-cold-backup&#34;&gt;Sync an already created cold backup.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Mount the existent pool&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Imagine your pool is at &lt;code&gt;/dev/sdf2&lt;/code&gt;:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Connect your device&lt;/li&gt; &lt;li&gt;Check for available ZFS pools: First, check if the system detects any ZFS pools that can be imported:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;import
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This command will list all pools that are available for import, including the one stored in &lt;code&gt;/dev/sdf2&lt;/code&gt;. Look for the pool name you want to import.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Import the pool: If you see the pool listed and you know its name (let&#39;s say the pool name is &lt;code&gt;mypool&lt;/code&gt;), you can import it with:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;import&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mypool
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Import the pool from a specific device: If the pool isn&#39;t showing up or you want to specify the device directly, you can use:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;import&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdf2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This tells ZFS to look specifically at &lt;code&gt;/dev/sdf2&lt;/code&gt; for any pools. If you don&#39;t know the name of the pool this is also the command to run.&lt;/p&gt; &lt;p&gt;This should list any pools found on the device. If it shows a pool, import it using:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;import&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdf2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;pool_name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Mount the pool: Once the pool is imported, ZFS should automatically mount any datasets associated with the pool. You can check the status of the pool with:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;status
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Additional options:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;If the pool was exported cleanly, you can use &lt;code&gt;zpool import&lt;/code&gt; without additional flags.&lt;/li&gt; &lt;li&gt;If the pool wasn’t properly exported or was interrupted, you might need to use &lt;code&gt;-f&lt;/code&gt; (force) to import it:&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;import&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mypool
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; feat(linux_snippets#Create a systemd service for a non-root user): Create a systemd service for a non-root user&lt;/p&gt; &lt;p&gt;To set up a systemd service as a &lt;strong&gt;non-root user&lt;/strong&gt;, you can create a user-specific service file under your home directory. User services are defined in &lt;code&gt;~/.config/systemd/user/&lt;/code&gt; and can be managed without root privileges.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Create the service file:&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;Open a terminal and create a new service file in &lt;code&gt;~/.config/systemd/user/&lt;/code&gt;. For example, if you want to create a service for a script named &lt;code&gt;my_script.py&lt;/code&gt;, follow these steps:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mkdir&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;~/.config/systemd/user
nano&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;~/.config/systemd/user/my_script.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt;Edit the service file:&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;In the &lt;code&gt;my_script.service&lt;/code&gt; file, add the following configuration:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[Unit]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;My Python Script Service&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;After&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;network.target&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Service]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;simple&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;ExecStart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/usr/bin/python3 /path/to/your/script/my_script.py&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;WorkingDirectory&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/path/to/your/script/&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;SyslogIdentifier&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;my_script&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Restart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;on-failure&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;StandardOutput&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;journal&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;StandardError&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;journal&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Install]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;WantedBy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;default.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Description&lt;/strong&gt;: A short description of what the service does.&lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;strong&gt;ExecStart&lt;/strong&gt;: The command to run your script. Replace &lt;code&gt;/path/to/your/script/my_script.py&lt;/code&gt; with the full path to your Python script. If you want to run the script within a virtualenv you can use &lt;code&gt;/path/to/virtualenv/bin/python&lt;/code&gt; instead of &lt;code&gt;/usr/bin/python3&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;You&#39;ll need to add the virtualenv path to Path &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;c1&#34;&gt;# Add virtualenv&#39;s bin directory to PATH&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Environment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;PATH=/path/to/virtualenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; - &lt;strong&gt;WorkingDirectory&lt;/strong&gt;: Set the working directory to where your script is located (optional). - &lt;strong&gt;Restart&lt;/strong&gt;: Restart the service if it fails. - &lt;strong&gt;StandardOutput&lt;/strong&gt; and &lt;strong&gt;StandardError&lt;/strong&gt;: This ensures that the output is captured in the systemd journal. - &lt;strong&gt;WantedBy&lt;/strong&gt;: Specifies the target to which this service belongs. &lt;code&gt;default.target&lt;/code&gt; is commonly used for user services.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Reload systemd to recognize the new service:&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Run the following command to reload systemd&#39;s user service files:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--user&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;daemon-reload
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt;Enable and start the service:&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;To start the service immediately and enable it to run on boot (for your user session), use the following commands:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--user&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;start&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;my_script.service
systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--user&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;enable&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;my_script.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt; &lt;p&gt;Check the status and logs:&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;To check if the service is running:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--user&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;status&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;my_script.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;To view logs specific to your service:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;journalctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--user&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-u&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;my_script.service&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;strong&gt;If you need to use the graphical interface&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If your script requires user interaction (like entering a GPG passphrase), it’s crucial to ensure that the service is tied to your graphical user session, which ensures that prompts can be displayed and interacted with.&lt;/p&gt; &lt;p&gt;To handle this situation, you should make a few adjustments to your systemd service:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Ensure service is bound to graphical session&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Change the &lt;code&gt;WantedBy&lt;/code&gt; target to &lt;code&gt;graphical-session.target&lt;/code&gt; instead of &lt;code&gt;default.target&lt;/code&gt;. This makes sure the service waits for the full graphical environment to be available.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Use &lt;code&gt;Type=forking&lt;/code&gt; instead of &lt;code&gt;Type=simple&lt;/code&gt; (optional)&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you need the service to wait until the user is logged in and has a desktop session ready, you might need to tweak the service type. Usually, &lt;code&gt;Type=simple&lt;/code&gt; is fine, but you can also experiment with &lt;code&gt;Type=forking&lt;/code&gt; if you notice any issues with user prompts.&lt;/p&gt; &lt;p&gt;Here’s how you should modify your &lt;code&gt;mbsync_syncer.service&lt;/code&gt; file:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[Unit]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;My Python Script Service&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;After&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;graphical-session.target&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Service]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;simple&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;ExecStart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/usr/bin/python3 /path/to/your/script/my_script.py&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;WorkingDirectory&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/path/to/your/script/&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Restart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;on-failure&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;StandardOutput&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;journal&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;StandardError&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;journal&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;SyslogIdentifier&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;my_script&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Environment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;DISPLAY=:0&#34;&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Environment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus&#34;&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Install]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;WantedBy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;graphical-session.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;After modifying the service, reload and restart it:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--user&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;daemon-reload
systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--user&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;restart&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;my_script.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;zfs-prometheus-exporter&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/zfs_exporter/&#34;&gt;ZFS Prometheus exporter&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Tweak the zfs_exporter target not available error.&lt;/p&gt; &lt;p&gt;Remember to set the &lt;code&gt;scrape_timeout&lt;/code&gt; to at least of &lt;code&gt;60s&lt;/code&gt; as the exporter is sometimes slow to answer, specially on low hardware resources.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;job_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;zfs_exporter&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metrics_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/metrics&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;scrape_timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;60s&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;static_configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;targets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;192.168.3.236&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;9134&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metric_relabel_configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Tweak the ZfsPoolUnhealthy alert.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ZfsPoolUnhealthy&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;last_over_time(zfs_pool_health[1h]) &amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;5m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;critical&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;resilience&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_resilience/&#34;&gt;Resilience&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce linux resilience.&lt;/p&gt; &lt;p&gt;Increasing the resilience of the servers is critical when hosting services for others. This is the roadmap I&#39;m following for my servers.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Autostart services if the system reboots&lt;/strong&gt; Using init system services to manage your services&lt;/p&gt; &lt;p&gt;**Get basic metrics traceability and alerts ** Set up &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/prometheus/&#34;&gt;Prometheus&lt;/a&gt; with:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/blackbox_exporter/&#34;&gt;blackbox exporter&lt;/a&gt; to track if the services are available to your users and to monitor SSL certificates health.&lt;/li&gt; &lt;li&gt;The &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/node_exporter/&#34;&gt;node exporter&lt;/a&gt; to keep track on the resource usage of your machines and set alerts to get notified when concerning events happen (disks are getting filled, CPU usage is too high)&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;**Get basic logs traceability and alerts **&lt;/p&gt; &lt;p&gt;Set up &lt;a href=&#34;https://lyz-code.github.io/blue-book/loki/&#34;&gt;Loki&lt;/a&gt; and clear up your system log errors.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Improve the resilience of your data&lt;/strong&gt; If you&#39;re still using &lt;code&gt;ext4&lt;/code&gt; for your filesystems instead of &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/&#34;&gt;&lt;code&gt;zfs&lt;/code&gt;&lt;/a&gt; you&#39;re missing a big improvement. To set it up:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/zfs_storage_planning/&#34;&gt;Plan your zfs storage architecture&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/&#34;&gt;Install ZFS&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/sanoid/&#34;&gt;Create ZFS local and remote backups&lt;/a&gt;&lt;/li&gt; &lt;li&gt;[Monitor your ZFS ]&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Automatically react on system failures&lt;/strong&gt; - &lt;a href=&#34;https://www.supertechcrew.com/kernel-panics-and-lockups/&#34;&gt;Kernel panics&lt;/a&gt; - &lt;a href=&#34;https://lyz-code.github.io/blue-book/watchdog/&#34;&gt;watchdog&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Future undeveloped improvements&lt;/strong&gt; - Handle the system reboots after kernel upgrades&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;memtest&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/memtest/&#34;&gt;Memtest&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce memtest.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.memtest86.com/&#34;&gt;memtest86&lt;/a&gt; is a testing software for RAM.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;memtest86+
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;After the installation you&#39;ll get Memtest entries in grub which you can spawn.&lt;/p&gt; &lt;p&gt;For some unknown reason the memtest of the boot menu didn&#39;t work for me. So I &lt;a href=&#34;https://www.memtest86.com/download.htm&#34;&gt;downloaded the latest free version of memtest&lt;/a&gt; (It&#39;s at the bottom of the screen), burnt it in a usb and booted from there.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt; It will run by itself. For 64GB of ECC RAM it took aproximately 100 minutes to run all the tests.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.memtest86.com/ecc.htm&#34;&gt;Check ECC errors&lt;/a&gt;&lt;/strong&gt; MemTest86 directly polls ECC errors logged in the chipset/memory controller registers and displays it to the user on-screen. In addition, ECC errors are written to the log and report file.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;watchdog_1&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/watchdog/&#34;&gt;watchdog&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the watchdog.&lt;/p&gt; &lt;p&gt;A &lt;a href=&#34;https://en.wikipedia.org/wiki/Watchdog_timer&#34;&gt;watchdog timer&lt;/a&gt; (WDT, or simply a watchdog), sometimes called a computer operating properly timer (COP timer), is an electronic or software timer that is used to detect and recover from computer malfunctions. Watchdog timers are widely used in computers to facilitate automatic correction of temporary hardware faults, and to prevent errant or malevolent software from disrupting system operation.&lt;/p&gt; &lt;p&gt;During normal operation, the computer regularly restarts the watchdog timer to prevent it from elapsing, or &#34;timing out&#34;. If, due to a hardware fault or program error, the computer fails to restart the watchdog, the timer will elapse and generate a timeout signal. The timeout signal is used to initiate corrective actions. The corrective actions typically include placing the computer and associated hardware in a safe state and invoking a computer reboot.&lt;/p&gt; &lt;p&gt;Microcontrollers often include an integrated, on-chip watchdog. In other computers the watchdog may reside in a nearby chip that connects directly to the CPU, or it may be located on an external expansion card in the computer&#39;s chassis.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Hardware watchdog&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Before you start using the hardware watchdog you need to check if your hardware actually supports it.&lt;/p&gt; &lt;p&gt;If you see &lt;a href=&#34;#watchdog-hardware-is-disabled-error-on-boot&#34;&gt;Watchdog hardware is disabled error on boot&lt;/a&gt; things are not looking good.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Check if the hardware watchdog is enabled&lt;/strong&gt; You can see if hardware watchdog is loaded by running &lt;code&gt;wdctl&lt;/code&gt;. For example for a machine that has it enabled you&#39;ll see:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Device:        /dev/watchdog0
Identity:      iTCO_wdt [version 0]
Timeout:       30 seconds
Pre-timeout:    0 seconds
Timeleft:      30 seconds
FLAG           DESCRIPTION               STATUS BOOT-STATUS
KEEPALIVEPING  Keep alive ping reply          1           0
MAGICCLOSE     Supports magic close char      0           0
SETTIMEOUT     Set timeout (in seconds)       0           0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;On a machine that doesn&#39;t you&#39;ll see:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;wdctl: No default device is available.: No such file or directory
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Another option is to run &lt;code&gt;dmesg | grep wd&lt;/code&gt; or &lt;code&gt;dmesg | grep watc -i&lt;/code&gt;. For example for a machine that has enabled the hardware watchdog you&#39;ll see something like:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[   20.708839] iTCO_wdt: Intel TCO WatchDog Timer Driver v1.11
[   20.708894] iTCO_wdt: Found a Intel PCH TCO device (Version=4, TCOBASE=0x0400)
[   20.709009] iTCO_wdt: initialized. heartbeat=30 sec (nowayout=0)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;For one that is not you&#39;ll see:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[    1.934999] sp5100_tco: SP5100/SB800 TCO WatchDog Timer Driver
[    1.935057] sp5100-tco sp5100-tco: Using 0xfed80b00 for watchdog MMIO address
[    1.935062] sp5100-tco sp5100-tco: Watchdog hardware is disabled
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you&#39;re out of luck and your hardware doesn&#39;t support it you can delegate the task to the software watchdog or get some &lt;a href=&#34;https://github.com/zatarra/usb-watchdog&#34;&gt;usb watchdog&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://0pointer.de/blog/projects/watchdog.html&#34;&gt;Systemd watchdog&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Starting with version 183 systemd provides full support for hardware watchdogs (as exposed in /dev/watchdog to userspace), as well as supervisor (software) watchdog support for invidual system services. The basic idea is the following: if enabled, systemd will regularly ping the watchdog hardware. If systemd or the kernel hang this ping will not happen anymore and the hardware will automatically reset the system. This way systemd and the kernel are protected from boundless hangs -- by the hardware. To make the chain complete, systemd then exposes a software watchdog interface for individual services so that they can also be restarted (or some other action taken) if they begin to hang. This software watchdog logic can be configured individually for each service in the ping frequency and the action to take. Putting both parts together (i.e. hardware watchdogs supervising systemd and the kernel, as well as systemd supervising all other services) we have a reliable way to watchdog every single component of the system.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://0pointer.de/blog/projects/watchdog.html&#34;&gt;Configuring the watchdog&lt;/a&gt;&lt;/strong&gt; To make use of the hardware watchdog it is sufficient to set the &lt;code&gt;RuntimeWatchdogSec=&lt;/code&gt; option in &lt;code&gt;/etc/systemd/system.conf&lt;/code&gt;. It defaults to &lt;code&gt;0&lt;/code&gt; (i.e. no hardware watchdog use). Set it to a value like &lt;code&gt;20s&lt;/code&gt; and the watchdog is enabled. After 20s of no keep-alive pings the hardware will reset itself. Note that &lt;code&gt;systemd&lt;/code&gt; will send a ping to the hardware at half the specified interval, i.e. every 10s.&lt;/p&gt; &lt;p&gt;Note that the hardware watchdog device (&lt;code&gt;/dev/watchdog&lt;/code&gt;) is single-user only. That means that you can either enable this functionality in systemd, or use a separate external watchdog daemon, such as the aptly named &lt;code&gt;watchdog&lt;/code&gt;. Although the built-in hardware watchdog support of systemd does not conflict with other watchdog software by default. systemd does not make use of &lt;code&gt;/dev/watchdog&lt;/code&gt; by default, and you are welcome to use external watchdog daemons in conjunction with systemd, if this better suits your needs.&lt;/p&gt; &lt;p&gt;&lt;code&gt;ShutdownWatchdogSec=`` is another option that can be configured in&lt;/code&gt;/etc/systemd/system.conf`. It controls the watchdog interval to use during reboots. It defaults to 10min, and adds extra reliability to the system reboot logic: if a clean reboot is not possible and shutdown hangs, we rely on the watchdog hardware to reset the system abruptly, as extra safety net.&lt;/p&gt; &lt;p&gt;Now, let&#39;s have a look how to add watchdog logic to individual services.&lt;/p&gt; &lt;p&gt;First of all, to make software watchdog-supervisable it needs to be patched to send out &#34;I am alive&#34; signals in regular intervals in its event loop. Patching this is relatively easy. First, a daemon needs to read the &lt;code&gt;WATCHDOG_USEC=&lt;/code&gt; environment variable. If it is set, it will contain the watchdog interval in usec formatted as ASCII text string, as it is configured for the service. The daemon should then issue &lt;code&gt;sd_notify(&#34;WATCHDOG=1&#34;)&lt;/code&gt; calls every half of that interval. A daemon patched this way should transparently support watchdog functionality by checking whether the environment variable is set and honouring the value it is set to.&lt;/p&gt; &lt;p&gt;To enable the software watchdog logic for a service (which has been patched to support the logic pointed out above) it is sufficient to set the &lt;code&gt;WatchdogSec=&lt;/code&gt; to the desired failure latency. See &lt;code&gt;systemd.service(5)&lt;/code&gt; for details on this setting. This causes &lt;code&gt;WATCHDOG_USEC=&lt;/code&gt; to be set for the service&#39;s processes and will cause the service to enter a failure state as soon as no keep-alive ping is received within the configured interval.&lt;/p&gt; &lt;p&gt;The next step is to configure whether the service shall be restarted and how often, and what to do if it then still fails. To enable automatic service restarts on failure set &lt;code&gt;Restart=on-failure&lt;/code&gt; for the service. To configure how many times a service shall be attempted to be restarted use the combination of &lt;code&gt;StartLimitBurst=&lt;/code&gt; and &lt;code&gt;StartLimitInterval=&lt;/code&gt; which allow you to configure how often a service may restart within a time interval. If that limit is reached, a special action can be taken. This action is configured with &lt;code&gt;StartLimitAction=&lt;/code&gt;. The default is a none, i.e. that no further action is taken and the service simply remains in the failure state without any further attempted restarts. The other three possible values are &lt;code&gt;reboot&lt;/code&gt;, &lt;code&gt;reboot-force&lt;/code&gt; and &lt;code&gt;reboot-immediate&lt;/code&gt;.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;reboot&lt;/code&gt; attempts a clean reboot, going through the usual, clean shutdown logic.&lt;/li&gt; &lt;li&gt;&lt;code&gt;reboot-force&lt;/code&gt; is more abrupt: it will not actually try to cleanly shutdown any services, but immediately kills all remaining services and unmounts all file systems and then forcibly reboots (this way all file systems will be clean but reboot will still be very fast).&lt;/li&gt; &lt;li&gt;&lt;code&gt;reboot-immediate&lt;/code&gt; does not attempt to kill any process or unmount any file systems. Instead it just hard reboots the machine without delay. &lt;code&gt;reboot-immediate&lt;/code&gt; hence comes closest to a reboot triggered by a hardware watchdog. All these settings are documented in &lt;code&gt;systemd.service(5)&lt;/code&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Putting this all together we now have pretty flexible options to watchdog-supervise a specific service and configure automatic restarts of the service if it hangs, plus take ultimate action if that doesn&#39;t help.&lt;/p&gt; &lt;p&gt;Here&#39;s an example unit file:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[Unit]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;My Little Daemon&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Documentation&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;man:mylittled(8)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Service]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;ExecStart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/usr/bin/mylittled&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;WatchdogSec&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;30s&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Restart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;on-failure&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;StartLimitInterval&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;5min&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;StartLimitBurst&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;4&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;StartLimitAction&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;reboot-force&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;````&lt;/span&gt;

&lt;span class=&#34;na&#34;&gt;This service will automatically be restarted if it hasn&#39;t pinged the system manager for longer than 30s or if it fails otherwise. If it is restarted this way more often than 4 times in 5min action is taken and the system quickly rebooted, with all file systems being clean when it comes up again.&lt;/span&gt;

&lt;span class=&#34;na&#34;&gt;To write the code of the watchdog service you can follow one of these guides&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;

&lt;span class=&#34;na&#34;&gt;- [Python based watchdog](https&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;//sleeplessbeastie.eu/2022/08/15/how-to-create-watchdog-for-systemd-service/)&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;- [Bash based watchdog](https&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;//www.medo64.com/2019/01/systemd-watchdog-for-any-service/)&lt;/span&gt;

&lt;span class=&#34;na&#34;&gt;**[Testing a watchdog](https&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;//serverfault.com/questions/375220/how-to-check-what-if-hardware-watchdogs-are-available-in-linux)**&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;One simple way to test a watchdog is to trigger a kernel panic. This can be done as root with&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;

&lt;span class=&#34;na&#34;&gt;```bash&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;echo c &amp;gt; /proc/sysrq-trigger&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The kernel will stop responding to the watchdog pings, so the watchdog will trigger.&lt;/p&gt; &lt;p&gt;SysRq is a &#39;magical&#39; key combo you can hit which the kernel will respond to regardless of whatever else it is doing, unless it is completely locked up. It can also be used by echoing letters to /proc/sysrq-trigger, like we&#39;re doing here.&lt;/p&gt; &lt;p&gt;In this case, the letter c means perform a system crash and take a crashdump if configured.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Troubleshooting&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Watchdog hardware is disabled error on boot&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;According to the discussion at &lt;a href=&#34;https://lore.kernel.org/linux-watchdog/20220509163304.86-1-mario.limonciello@amd.com/T/#u&#34;&gt;the kernel mailing list&lt;/a&gt; it means that the system contains hardware watchdog but it has been disabled (probably by BIOS) and Linux cannot enable the hardware.&lt;/p&gt; &lt;p&gt;If your BIOS doesn&#39;t have a switch to enable it, consider the watchdog hardware broken for your system.&lt;/p&gt; &lt;p&gt;Some people are blacklisting the module so that it&#39;s not loaded and therefore it doesn&#39;t return the error (&lt;a href=&#34;https://www.reddit.com/r/openSUSE/comments/a3nmg5/watchdog_hardware_is_disabled_on_boot/&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;https://bbs.archlinux.org/viewtopic.php?id=239075&#34;&gt;2&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://0pointer.de/blog/projects/watchdog.html&#34;&gt;0pointer post on systemd watchdogs&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://blog.heckel.io/2020/10/08/reliably-rebooting-ubuntu-using-watchdogs/&#34;&gt;Heckel post on how to reboot using watchdogs&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;magic-keys&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/magic_keys/&#34;&gt;Magic keys&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the Magic Keys.&lt;/p&gt; &lt;p&gt;The magic SysRq key is a key combination understood by the Linux kernel, which allows the user to perform various low-level commands regardless of the system&#39;s state. It is often used to recover from freezes, or to reboot a computer without corrupting the filesystem.[1] Its effect is similar to the computer&#39;s hardware reset button (or power switch) but with many more options and much more control.&lt;/p&gt; &lt;p&gt;This key combination provides access to powerful features for software development and disaster recovery. In this sense, it can be considered a form of escape sequence. Principal among the offered commands are means to forcibly unmount file systems, kill processes, recover keyboard state, and write unwritten data to disk. With respect to these tasks, this feature serves as a tool of last resort.&lt;/p&gt; &lt;p&gt;The magic SysRq key cannot work under certain conditions, such as a kernel panic[2] or a hardware failure preventing the kernel from running properly.&lt;/p&gt; &lt;p&gt;The key combination consists of Alt+Sys Req and another key, which controls the command issued.&lt;/p&gt; &lt;p&gt;On some devices, notably laptops, the Fn key may need to be pressed to use the magic SysRq key.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Reboot the machine&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;A common use of the magic SysRq key is to perform a safe reboot of a Linux computer which has otherwise locked up (abbr. REISUB). This can prevent a fsck being required on reboot and gives some programs a chance to save emergency backups of unsaved work. The QWERTY (or AZERTY) mnemonics: &#34;Raising Elephants Is So Utterly Boring&#34;, &#34;Reboot Even If System Utterly Broken&#34; or simply the word &#34;BUSIER&#34; read backwards, are often used to remember the following SysRq-keys sequence:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;unRaw (take control of keyboard back from X),&lt;/li&gt; &lt;li&gt;tErminate (send SIGTERM to all processes, allowing them to terminate gracefully),&lt;/li&gt; &lt;li&gt;kIll (send SIGKILL to all processes, forcing them to terminate immediately),&lt;/li&gt; &lt;li&gt;Sync (flush data to disk),&lt;/li&gt; &lt;li&gt;Unmount (remount all filesystems read-only),&lt;/li&gt; &lt;li&gt;reBoot.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;When magic SysRq keys are used to kill a frozen graphical program, the program has no chance to restore text mode. This can make everything unreadable. The commands textmode (part of SVGAlib) and the reset command can restore text mode and make the console readable again.&lt;/p&gt; &lt;p&gt;On distributions that do not include a textmode executable, the key command Ctrl+Alt+F1 may sometimes be able to force a return to a text console. (Use F1, F2, F3,..., F(n), where n is the highest number of text consoles set up by the distribution. Ctrl+Alt+F(n+1) would normally be used to reenter GUI mode on a system on which the X server has not crashed.)&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://unix.stackexchange.com/questions/714910/what-is-a-good-way-to-test-watchdog-script-or-command-to-deliberately-overload&#34;&gt;Interact with the sysrq through the commandline&lt;/a&gt;&lt;/strong&gt; It can also be used by echoing letters to &lt;code&gt;/proc/sysrq-trigger&lt;/code&gt;, for example to trigger a system crash and take a crashdump you can:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/sysrq-trigger
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;monitoring&#34;&gt;Monitoring&lt;/h3&gt; &lt;h4 id=&#34;loki&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/loki/&#34;&gt;Loki&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/loki/#prevent-the-too-many-outstanding-requests-error&#34;&gt;Prevent the too many outstanding requests error.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Add to your loki config the next options &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;limits_config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;split_queries_by_interval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;24h&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;max_query_parallelism&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;100&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;query_scheduler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;max_outstanding_requests_per_tenant&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;4096&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;frontend&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;max_outstanding_per_tenant&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;4096&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/loki/#installation&#34;&gt;Use &lt;code&gt;fake&lt;/code&gt; when using one loki instance in docker.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you only have one Loki instance you need to save the rule yaml files in the &lt;code&gt;/etc/loki/rules/fake/&lt;/code&gt; otherwise Loki will silently ignore them (it took me a lot of time to figure this out &lt;code&gt;-.-&lt;/code&gt;).&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add alerts.&lt;/p&gt; &lt;p&gt;Surprisingly I haven&#39;t found any compilation of Loki alerts. I&#39;ll gather here the ones I create.&lt;/p&gt; &lt;p&gt;There are two kinds of rules: alerting rules and recording rules.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/rasdaemon/#monitorization&#34;&gt;ECC error alerts&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#zfs-pool-is-stuck&#34;&gt;ZFS errors&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/sanoid/#monitorization&#34;&gt;Sanoid errors&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/loki/#alert-when-query-returns-no-data&#34;&gt;Alert when query returns no data.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Sometimes the queries you want to alert happen when the return value is NaN or No Data. For example if you want to monitory the happy path by setting an alert if a string is not found in some logs in a period of time.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;count_over_time({filename=&#34;/var/log/mail.log&#34;} |= `Mail is sent` [24h]) &amp;lt; 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This won&#39;t trigger the alert because the &lt;code&gt;count_over_time&lt;/code&gt; doesn&#39;t return a &lt;code&gt;0&lt;/code&gt; but a &lt;code&gt;NaN&lt;/code&gt;. One way to solve it is to use &lt;a href=&#34;https://github.com/grafana/loki/pull/7023&#34;&gt;the &lt;code&gt;vector(0)&lt;/code&gt;&lt;/a&gt; operator with &lt;a href=&#34;https://stackoverflow.com/questions/76489956/how-to-return-a-zero-vector-in-loki-logql-metric-query-when-grouping-is-used-and&#34;&gt;the operation &lt;code&gt;or on() vector(0)&lt;/code&gt;&lt;/a&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;(count_over_time({filename=&#34;/var/log/mail.log&#34;} |= `Mail is sent` [24h]) or on() vector(0)) &amp;lt; 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/loki/#monitor-loki-metrics&#34;&gt;Monitor loki metrics.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Since Loki reuses the Prometheus code for recording rules and WALs, it also gains all of Prometheus’ observability.&lt;/p&gt; &lt;p&gt;To scrape loki metrics with prometheus add the next snippet to the prometheus configuration:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;job_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;loki&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metrics_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/metrics&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;static_configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;targets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;loki:3100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This assumes that &lt;code&gt;loki&lt;/code&gt; is a docker in the same network as &lt;code&gt;prometheus&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;There are some rules in the &lt;a href=&#34;https://samber.github.io/awesome-prometheus-alerts/rules#loki&#34;&gt;awesome prometheus alerts repo&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;groups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Awesome Prometheus loki alert rules&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# https://samber.github.io/awesome-prometheus-alerts/rules#loki&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;LokiProcessTooManyRestarts&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;changes(process_start_time_seconds{job=~&#34;.*loki.*&#34;}[15m]) &amp;gt; 2&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Loki process too many restarts (instance {{ $labels.instance }})&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;A&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;loki&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;process&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;had&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;too&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;many&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;restarts&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(target&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;LokiRequestErrors&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;100 * sum(rate(loki_request_duration_seconds_count{status_code=~&#34;5..&#34;}[1m])) by (namespace, job, route) / sum(rate(loki_request_duration_seconds_count[1m])) by (namespace, job, route) &amp;gt; 10&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;15m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;critical&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Loki request errors (instance {{ $labels.instance }})&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.job&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;and&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.route&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;are&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;experiencing&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;errors\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;LokiRequestPanic&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;sum(increase(loki_panic_total[10m])) by (namespace, job) &amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;5m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;critical&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Loki request panic (instance {{ $labels.instance }})&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.job&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;experiencing&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;\&#34;%.2f\&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}%&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;increase&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;of&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;panics\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;LokiRequestLatency&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;(histogram_quantile(0.99, sum(rate(loki_request_duration_seconds_bucket{route!~&#34;(?i).*tail.*&#34;}[5m])) by (le)))  &amp;gt; 1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;5m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;critical&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Loki request latency (instance {{ $labels.instance }})&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.job&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.route&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;experiencing&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;\&#34;%.2f\&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}s&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;99th&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;percentile&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;latency\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;And there are some guidelines on the rest of the metrics in &lt;a href=&#34;https://grafana.com/docs/loki/latest/operations/observability/&#34;&gt;the grafana documentation&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://grafana.com/docs/loki/latest/operations/recording-rules/&#34;&gt;Monitor the ruler&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Prometheus exposes a number of metrics for its WAL implementation, and these have all been prefixed with &lt;code&gt;loki_ruler_wal_&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;For example: &lt;code&gt;prometheus_remote_storage_bytes_total&lt;/code&gt; → &lt;code&gt;loki_ruler_wal_prometheus_remote_storage_bytes_total&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Additional metrics are exposed, also with the prefix &lt;code&gt;loki_ruler_wal_&lt;/code&gt;. All per-tenant metrics contain a tenant label, so be aware that cardinality could begin to be a concern if the number of tenants grows sufficiently large.&lt;/p&gt; &lt;p&gt;Some key metrics to note are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;loki_ruler_wal_appender_ready&lt;/code&gt;: whether a WAL appender is ready to accept samples (1) or not (0)&lt;/li&gt; &lt;li&gt;&lt;code&gt;loki_ruler_wal_prometheus_remote_storage_samples_total&lt;/code&gt;: number of samples sent per tenant to remote storage&lt;/li&gt; &lt;li&gt;&lt;code&gt;loki_ruler_wal_prometheus_remote_storage_samples_pending_total&lt;/code&gt;: samples buffered in memory, waiting to be sent to remote storage&lt;/li&gt; &lt;li&gt;&lt;code&gt;loki_ruler_wal_prometheus_remote_storage_samples_failed_total&lt;/code&gt;: samples that failed when sent to remote storage&lt;/li&gt; &lt;li&gt;&lt;code&gt;loki_ruler_wal_prometheus_remote_storage_samples_dropped_total&lt;/code&gt;: samples dropped by relabel configurations&lt;/li&gt; &lt;li&gt;&lt;code&gt;loki_ruler_wal_prometheus_remote_storage_samples_retried_total&lt;/code&gt;: samples re-resent to remote storage&lt;/li&gt; &lt;li&gt;&lt;code&gt;loki_ruler_wal_prometheus_remote_storage_highest_timestamp_in_seconds&lt;/code&gt;: highest timestamp of sample appended to WAL&lt;/li&gt; &lt;li&gt;&lt;code&gt;loki_ruler_wal_prometheus_remote_storage_queue_highest_sent_timestamp_seconds&lt;/code&gt;: highest timestamp of sample sent to remote storage.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/loki/#get-a-useful-source-link-in-the-alertmanager&#34;&gt;Get a useful Source link in the alertmanager.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/grafana/loki/issues/4722&#34;&gt;This still doesn&#39;t work&lt;/a&gt;. Currently for the ruler &lt;code&gt;external_url&lt;/code&gt; if you use the URL of your Grafana installation: e.g. &lt;code&gt;external_url: &#34;https://grafana.example.com&#34;&lt;/code&gt; it creates a Source link in alertmanager similar to &lt;a href=&#34;https://grafana.example.com/graph?g0.expr=%28sum+by%28thing%29%28count_over_time%28%7Bnamespace%3D%22foo%22%7D+%7C+json+%7C+bar%3D%22maxRetries%22%5B5m%5D%29%29+%3E+0%29&amp;amp;g0.tab=1&#34;&gt;https://grafana.example.com/graph?g0.expr=%28sum+by%28thing%29%28count_over_time%28%7Bnamespace%3D%22foo%22%7D+%7C+json+%7C+bar%3D%22maxRetries%22%5B5m%5D%29%29+%3E+0%29&amp;amp;g0.tab=1&lt;/a&gt;, which isn&#39;t valid.&lt;/p&gt; &lt;p&gt;This url templating (via &lt;code&gt;/graph?g0.expr=%s&amp;amp;g0.tab=1&lt;/code&gt;) appears to be coming from prometheus. There is not a workaround yet&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/loki/#maximum-of-series-reached-for-a-single-query&#34;&gt;Maximum of series reached for a single query.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Go to the loki-local-config.yaml, then find the limits_config configuration. Then modify this to the limits_config:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;limits_config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;max_query_series&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;100000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;But probably you&#39;re doing something wrong. feat(orgzly#Both local and remote notebook have been modified): Both local and remote notebook have been modified&lt;/p&gt; &lt;p&gt;You can force load or force save a single note with a long tap.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Don&#39;t use vector(0) on aggregation over labels.&lt;/p&gt; &lt;p&gt;If you&#39;re doing an aggregation over a label this approach won&#39;t work because it will add a new time series with value 0. In those cases use a broader search that includes other logs from the label you&#39;re trying to aggregate and multiply it by 0. For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;(
sum by (hostname) (
  count_over_time({job=&#34;systemd-journal&#34;, syslog_identifier=&#34;sanoid&#34;}[1h])
)
or
sum by (hostname) (
  count_over_time({job=&#34;systemd-journal&#34;}[1h]) * 0
)
) &amp;lt; 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The first part of the query returns all log lines of the service &lt;code&gt;sanoid&lt;/code&gt; for each &lt;code&gt;hostname&lt;/code&gt;. If one hostname were not to return any line that query alone won&#39;t show anything for that host. The second part of the query counts all the log lines of each &lt;code&gt;hostname&lt;/code&gt;, so if it&#39;s up it will probably be sending at least one line per hour. As we&#39;re not interested in those number of lines we multiply it by 0, so that the target is shown.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/loki/#interact-with-loki-through-python&#34;&gt;Interact with loki through python.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;There is &lt;a href=&#34;https://community.grafana.com/t/how-could-i-pull-loki-records-from-a-python-script/111483/4&#34;&gt;no client library for python&lt;/a&gt; (&lt;a href=&#34;https://stackoverflow.com/questions/75056462/querying-loki-logs-using-python&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;https://stackoverflow.com/questions/75056462/querying-loki-logs-using-python&#34;&gt;2&lt;/a&gt;) they suggest to interact with the &lt;a href=&#34;https://grafana.com/docs/loki/latest/reference/loki-http-api/&#34;&gt;API&lt;/a&gt; with &lt;code&gt;requests&lt;/code&gt;. Although I&#39;d rather use &lt;a href=&#34;https://lyz-code.github.io/blue-book/logcli/&#34;&gt;&lt;code&gt;logcli&lt;/code&gt;&lt;/a&gt; with the &lt;a href=&#34;https://lyz-code.github.io/blue-book/python_sh/&#34;&gt;&lt;code&gt;sh&lt;/code&gt;&lt;/a&gt; library.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/loki/#download-the-logs&#34;&gt;Download the logs.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The web UI only allows you to download the logs that are loaded in the view, if you want to download big amounts of logs you need to either use &lt;a href=&#34;https://lyz-code.github.io/blue-book/logcli/&#34;&gt;&lt;code&gt;logcli&lt;/code&gt;&lt;/a&gt; or interact with the &lt;a href=&#34;https://grafana.com/docs/loki/latest/reference/loki-http-api/&#34;&gt;API&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;One user did a query on loop:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-x

&lt;span class=&#34;nv&#34;&gt;JOB_ID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;9079dc54-2f5c-4d74-a9aa-1d9eb39dd3c2

&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;I&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;seq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;655&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;FILE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;logs_&lt;span class=&#34;nv&#34;&gt;$I&lt;/span&gt;.txt
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$JOB_ID&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$I&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;QUERY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;{aws_job_id=\&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ID&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;\&#34;,job=\&#34;varlogs\&#34;}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;run&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grafana/logcli:main-1b6d0bf-amd64&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--addr&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;http://localhost:3100/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;raw&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-q&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;query&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$QUERY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--limit&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;100000&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--batch&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--forward&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--from&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;2022-09-25T10:00:00Z&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$FILE&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;logcli&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/promtail/&#34;&gt;Logcli&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Promtail.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://grafana.com/docs/loki/latest/send-data/promtail/&#34;&gt;Promtail&lt;/a&gt; is an agent which ships the contents of local logs to a &lt;a href=&#34;https://lyz-code.github.io/blue-book/loki/&#34;&gt;Loki&lt;/a&gt; instance.&lt;/p&gt; &lt;p&gt;It is usually deployed to every machine that runs applications which need to be monitored.&lt;/p&gt; &lt;p&gt;It primarily:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Discovers targets&lt;/li&gt; &lt;li&gt;Attaches labels to log streams&lt;/li&gt; &lt;li&gt;Pushes them to the Loki instance.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/promtail/#scrape-journald-logs&#34;&gt;Scrape journald logs.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;On systems with &lt;code&gt;systemd&lt;/code&gt;, Promtail also supports reading from the journal. Unlike file scraping which is defined in the &lt;code&gt;static_configs&lt;/code&gt; stanza, journal scraping is defined in a &lt;code&gt;journal&lt;/code&gt; stanza:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;scrape_configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;job_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;journal&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;journal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;false&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;max_age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;12h&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/var/log/journal&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;job&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;systemd-journal&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;relabel_configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;source_labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;__journal__systemd_unit&#39;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;target_label&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;unit&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;source_labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;__journal__hostname&#39;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;target_label&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;hostname&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;source_labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;__journal_syslog_identifier&#39;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;target_label&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;syslog_identifier&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;source_labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;__journal_transport&#39;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;target_label&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;transport&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;source_labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;__journal_priority_keyword&#39;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;target_label&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;keyword&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;All fields defined in the journal section are optional, and are just provided here for reference.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;max_age&lt;/code&gt; ensures that no older entry than the time specified will be sent to Loki; this circumvents &lt;code&gt;entry too old&lt;/code&gt; errors.&lt;/li&gt; &lt;li&gt;&lt;code&gt;path&lt;/code&gt; tells Promtail where to read journal entries from.&lt;/li&gt; &lt;li&gt;&lt;code&gt;labels&lt;/code&gt; map defines a constant list of labels to add to every journal entry that Promtail reads.&lt;/li&gt; &lt;li&gt;&lt;code&gt;matches&lt;/code&gt; field adds journal filters. If multiple filters are specified matching different fields, the log entries are filtered by both, if two filters apply to the same field, then they are automatically matched as alternatives.&lt;/li&gt; &lt;li&gt;When the &lt;code&gt;json&lt;/code&gt; field is set to true, messages from the journal will be passed through the pipeline as JSON, keeping all of the original fields from the journal entry. This is useful when you don’t want to index some fields but you still want to know what values they contained.&lt;/li&gt; &lt;li&gt;When Promtail reads from the journal, it brings in all fields prefixed with &lt;code&gt;__journal_&lt;/code&gt; as internal labels. Like in the example above, the &lt;code&gt;_SYSTEMD_UNIT&lt;/code&gt; field from the journal was transformed into a label called &lt;code&gt;unit&lt;/code&gt; through &lt;code&gt;relabel_configs&lt;/code&gt;. Keep in mind that labels prefixed with &lt;code&gt;__&lt;/code&gt; will be dropped, so relabeling is required to keep these labels. Look at the &lt;a href=&#34;https://www.freedesktop.org/software/systemd/man/latest/systemd.journal-fields.html&#34;&gt;systemd man pages&lt;/a&gt; for a list of fields exposed by the journal.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;By default, Promtail reads from the journal by looking in the &lt;code&gt;/var/log/journal&lt;/code&gt; and &lt;code&gt;/run/log/journal&lt;/code&gt; paths. If running Promtail inside of a Docker container, the path appropriate to your distribution should be bind mounted inside of Promtail along with binding &lt;code&gt;/etc/machine-id&lt;/code&gt;. Bind mounting &lt;code&gt;/etc/machine-id&lt;/code&gt; to the path of the same name is required for the journal reader to know which specific journal to read from.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;run&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/log/journal/:/var/log/journal/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/run/log/journal/:/run/log/journal/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/machine-id:/etc/machine-id&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;grafana/promtail:latest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-config.file&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/path/to/config/file.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/promtail/#scrape-docker-logs&#34;&gt;Scrape docker logs.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Docker service discovery allows retrieving targets from a Docker daemon. It will only watch containers of the Docker daemon referenced with the host parameter. Docker service discovery should run on each node in a distributed setup. The containers must run with either the &lt;code&gt;json-file&lt;/code&gt; or &lt;code&gt;journald&lt;/code&gt; logging driver.&lt;/p&gt; &lt;p&gt;Note that the discovery will not pick up finished containers. That means Promtail will not scrape the remaining logs from finished containers after a restart.&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;scrape_configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;job_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;docker&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;docker_sd_configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;host&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;unix:///var/run/docker.sock&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;refresh_interval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;5s&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;relabel_configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;source_labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;__meta_docker_container_id&#39;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;target_label&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;docker_id&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;source_labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;__meta_docker_container_name&#39;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;target_label&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;docker_name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; The available meta labels are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;__meta_docker_container_id&lt;/code&gt;: the ID of the container&lt;/li&gt; &lt;li&gt;&lt;code&gt;__meta_docker_container_name&lt;/code&gt;: the name of the container&lt;/li&gt; &lt;li&gt;&lt;code&gt;__meta_docker_container_network_mode&lt;/code&gt;: the network mode of the container&lt;/li&gt; &lt;li&gt;&lt;code&gt;__meta_docker_container_label_&amp;lt;labelname&amp;gt;&lt;/code&gt;: each label of the container&lt;/li&gt; &lt;li&gt;&lt;code&gt;__meta_docker_container_log_stream&lt;/code&gt;: the log stream type stdout or stderr&lt;/li&gt; &lt;li&gt;&lt;code&gt;__meta_docker_network_id&lt;/code&gt;: the ID of the network&lt;/li&gt; &lt;li&gt;&lt;code&gt;__meta_docker_network_name&lt;/code&gt;: the name of the network&lt;/li&gt; &lt;li&gt;&lt;code&gt;__meta_docker_network_ingress&lt;/code&gt;: whether the network is ingress&lt;/li&gt; &lt;li&gt;&lt;code&gt;__meta_docker_network_internal&lt;/code&gt;: whether the network is internal&lt;/li&gt; &lt;li&gt;&lt;code&gt;__meta_docker_network_label_&amp;lt;labelname&amp;gt;&lt;/code&gt;: each label of the network&lt;/li&gt; &lt;li&gt;&lt;code&gt;__meta_docker_network_scope&lt;/code&gt;: the scope of the network&lt;/li&gt; &lt;li&gt;&lt;code&gt;__meta_docker_network_ip&lt;/code&gt;: the IP of the container in this network&lt;/li&gt; &lt;li&gt;&lt;code&gt;__meta_docker_port_private&lt;/code&gt;: the port on the container&lt;/li&gt; &lt;li&gt;&lt;code&gt;__meta_docker_port_public&lt;/code&gt;: the external port if a port-mapping exists&lt;/li&gt; &lt;li&gt;&lt;code&gt;__meta_docker_port_public_ip&lt;/code&gt;: the public IP if a port-mapping exists&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;These labels can be used during relabeling. For instance, the following configuration scrapes the container named &lt;code&gt;flog&lt;/code&gt; and removes the leading slash (/) from the container name. yaml&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;scrape_configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;job_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;flog_scrape&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;docker_sd_configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;host&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;unix:///var/run/docker.sock&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;refresh_interval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;5s&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;filters&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;name&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;values&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;flog&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;relabel_configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;source_labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;__meta_docker_container_name&#39;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;regex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;/(.*)&#39;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;target_label&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;container&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/promtail/#pipeline-building&#34;&gt;Pipeline building.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;In &lt;a href=&#34;https://github.com/grafana/loki/issues/6165&#34;&gt;this issue&lt;/a&gt; there are nice examples on different pipelines.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/promtail/#drop-logs&#34;&gt;Drop logs.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you don&#39;t want the logs that have the keyword &lt;code&gt;systemd-journal&lt;/code&gt; and value &lt;code&gt;docker-compose&lt;/code&gt; you can add the next pipeline stage:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;pipeline_stages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;drop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;syslog_identifier&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;docker-compose&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/promtail/#installation&#34;&gt;Install with ansible.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use &lt;a href=&#34;https://github.com/patrickjahns/ansible-role-promtail&#34;&gt;patrickjahns ansible role&lt;/a&gt;. Some interesting variables are:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;loki_url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;localhost&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;promtail_system_user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;root&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;promtail_config_clients&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;http://{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;loki_url&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}:3100/loki/api/v1/push&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;external_labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;hostname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;ansible_hostname&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/promtail/#troubleshooting&#34;&gt;Troubleshooting promtail.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Find where is the &lt;code&gt;positions.yaml&lt;/code&gt; file and see if it evolves.&lt;/p&gt; &lt;p&gt;Sometimes if you are not seeing the logs in loki it&#39;s because the query you&#39;re running is not correct.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/promtail/#set-the-hostname-label-on-all-logs&#34;&gt;Set the hostname label on all logs.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;There are many ways to do it:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://community.grafana.com/t/how-to-add-variable-hostname-label-to-static-config-in-promtail/68352/11&#34;&gt;Setting the label in the promtail launch command&lt;/a&gt; &lt;code&gt;bash sudo ./promtail-linux-amd64 --client.url=http://xxxx:3100/loki/api/v1/push --client.external-labels=hostname=$(hostname) --config.file=./config.yaml&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;This won&#39;t work if you&#39;re using promtail within a docker-compose because you can&#39;t use bash expansion in the &lt;code&gt;docker-compose.yaml&lt;/code&gt; file - &lt;a href=&#34;https://github.com/grafana/loki/issues/634&#34;&gt;Allowing env expansion and setting it in the promtail conf&lt;/a&gt;. You can launch the promtail command with &lt;code&gt;-config.expand-env&lt;/code&gt; and then set in each scrape jobs: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;host&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;${HOSTNAME}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; This won&#39;t work either if you&#39;re using &lt;code&gt;promtail&lt;/code&gt; within a docker as it will give you the ID of the docker - Set it in the &lt;code&gt;promtail_config_clients&lt;/code&gt; field as &lt;code&gt;external_labels&lt;/code&gt; of each promtail config: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;promtail_config_clients&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;http://{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;loki_url&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}:3100/loki/api/v1/push&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;external_labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;hostname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;ansible_hostname&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; - Hardcode it for each promtail config scraping config as static labels. If you&#39;re using ansible or any deployment method that supports jinja expansion set it that way &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;host&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ansible_hostname&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce logcli.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://grafana.com/docs/loki/latest/query/logcli/&#34;&gt;&lt;code&gt;logcli&lt;/code&gt;&lt;/a&gt; is the command-line interface to Grafana Loki. It facilitates running LogQL queries against a Loki instance.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://grafana.com/docs/loki/latest/query/logcli/#installation&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt; Download the logcli binary from the &lt;a href=&#34;https://github.com/grafana/loki/releases&#34;&gt;Loki releases page&lt;/a&gt; and install it somewhere in your &lt;code&gt;$PATH&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://grafana.com/docs/loki/latest/query/logcli/#logcli-usage&#34;&gt;Usage&lt;/a&gt;&lt;/strong&gt; &lt;code&gt;logcli&lt;/code&gt; points to the local instance &lt;code&gt;http://localhost:3100&lt;/code&gt; directly, if you want another one export the &lt;code&gt;LOKI_ADDR&lt;/code&gt; environment variable.&lt;/p&gt; &lt;p&gt;Run a query:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;logcli&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;query&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;{job=&#34;loki-ops/consul&#34;}&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can also set the time range and output format&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;logcli&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;query&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;--timezone&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;UTC&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;--from&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;2024-06-10T07:23:36Z&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;--to&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;2024-06-12T16:23:58Z&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;--output&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;jsonl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;{job=&#34;docker&#34;, container=&#34;aleph_ingest-file_1&#34;} | json | __error__=`` | severity =~ `WARNING|ERROR` | message !~ `Queueing failed task for retry.*` | logger!=`ingestors.manager`&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://grafana.com/docs/loki/latest/query/logcli/&#34;&gt;Docs&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;grafana&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/grafana/&#34;&gt;Grafana&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/grafana/#copy-panels-between-dashboards&#34;&gt;Copy panels between dashboards.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;On each panel on the top right you can select &lt;code&gt;copy&lt;/code&gt;, then on the menu to add a new panel you can click on &lt;code&gt;Paste panel from clipboard&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;So far you &lt;a href=&#34;https://github.com/grafana/grafana/issues/23762&#34;&gt;can&#39;t do this for rows&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;alertmanager&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/alertmanager/&#34;&gt;AlertManager&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Add another source on how to silence alerts.&lt;/p&gt; &lt;p&gt;If previous guidelines don&#39;t work for you, you can use the &lt;a href=&#34;https://samber.github.io/awesome-prometheus-alerts/sleep-peacefully&#34;&gt;sleep peacefully guidelines&lt;/a&gt; to tackle it at query level.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Using time intervals.&lt;/p&gt; &lt;p&gt;The values of &lt;code&gt;time_intervals&lt;/code&gt; can be:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;- &amp;lt;time_range&amp;gt; ...&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;weekdays&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;- &amp;lt;weekday_range&amp;gt; ...&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;days_of_month&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;- &amp;lt;days_of_month_range&amp;gt; ...&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;months&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;- &amp;lt;month_range&amp;gt; ...&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;years&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;- &amp;lt;year_range&amp;gt; ...&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;location&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;All fields are lists. Within each non-empty list, at least one element must be satisfied to match the field. If a field is left unspecified, any value will match the field. For an instant of time to match a complete time interval, all fields must match. Some fields support ranges and negative indices, and are detailed below. If a time zone is not specified, then the times are taken to be in UTC.&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;&lt;code&gt;time_range&lt;/code&gt;: Ranges inclusive of the starting time and exclusive of the end time to make it easy to represent times that start/end on hour boundaries. For example, &lt;code&gt;start_time: &#39;17:00&#39;&lt;/code&gt; and &lt;code&gt;end_time: &#39;24:00&#39;&lt;/code&gt; will begin at 17:00 and finish immediately before 24:00. They are specified like so: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;start_time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;HH:MM&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;end_time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;HH:MM&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;code&gt;weekday_range&lt;/code&gt;: A list of days of the week, where the week begins on Sunday and ends on Saturday. Days should be specified by name (e.g. &#39;Sunday&#39;). For convenience, ranges are also accepted of the form &lt;code&gt;&amp;lt;start_day&amp;gt;:&amp;lt;end_day&amp;gt;&lt;/code&gt; and are inclusive on both ends. For example: &lt;code&gt;[&#39;monday:wednesday&#39;,&#39;saturday&#39;, &#39;sunday&#39;]&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;code&gt;days_of_month_range&lt;/code&gt;: A list of numerical days in the month. Days begin at &lt;code&gt;1&lt;/code&gt;. Negative values are also accepted which begin at the end of the month, e.g. &lt;code&gt;-1&lt;/code&gt; during January would represent January 31. For example: &lt;code&gt;[&#39;1:5&#39;, &#39;-3:-1&#39;]&lt;/code&gt;. Extending past the start or end of the month will cause it to be clamped. E.g. specifying &lt;code&gt;[&#39;1:31&#39;]&lt;/code&gt; during February will clamp the actual end date to 28 or 29 depending on leap years. Inclusive on both ends.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;code&gt;month_range&lt;/code&gt;: A list of calendar months identified by a case-insensitive name (e.g. &#39;January&#39;) or by number, where &lt;code&gt;January = 1&lt;/code&gt;. Ranges are also accepted. For example, &lt;code&gt;[&#39;1:3&#39;, &#39;may:august&#39;, &#39;december&#39;]&lt;/code&gt;. Inclusive on both ends.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;code&gt;year_range&lt;/code&gt;: A numerical list of years. Ranges are accepted. For example, &lt;code&gt;[&#39;2020:2022&#39;, &#39;2030&#39;]&lt;/code&gt;. Inclusive on both ends.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;code&gt;location&lt;/code&gt;: A string that matches a location in the IANA time zone database. For example, &lt;code&gt;&#39;Australia/Sydney&#39;&lt;/code&gt;. The location provides the time zone for the time interval. For example, a time interval with a location of &lt;code&gt;&#39;Australia/Sydney&#39;&lt;/code&gt; that contained something like:&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;start_time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;09:00&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;end_time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;17:00&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;weekdays&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;monday:friday&#39;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Would include any time that fell between the hours of 9:00AM and 5:00PM, between Monday and Friday, using the local time in Sydney, Australia. You may also use &lt;code&gt;&#39;Local&#39;&lt;/code&gt; as a location to use the local time of the machine where Alertmanager is running, or &lt;code&gt;&#39;UTC&#39;&lt;/code&gt; for UTC time. If no timezone is provided, the time interval is taken to be in UTC.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;process-exporter&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/process_exporter/&#34;&gt;Process Exporter&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the process exporter.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/ncabatoff/process-exporter?tab=readme-ov-file&#34;&gt;&lt;code&gt;process_exporter&lt;/code&gt;&lt;/a&gt; is a rometheus exporter that mines /proc to report on selected processes.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt; - &lt;a href=&#34;https://github.com/ncabatoff/process-exporter?tab=readme-ov-file&#34;&gt;Source&lt;/a&gt; - &lt;a href=&#34;https://grafana.com/grafana/dashboards/249-named-processes/&#34;&gt;Grafana dashboard&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;databases&#34;&gt;Databases&lt;/h3&gt; &lt;h4 id=&#34;postgresql&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/postgres/&#34;&gt;PostgreSQL&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/postgres/#store-expensive-calculation-values-in-a-postgresql-database&#34;&gt;Store expensive calculation values in a postgresql database.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;First you need to think if you actually need to store the calculations or you can do them on the fly with &lt;a href=&#34;#views&#34;&gt;views&lt;/a&gt;. If views are too slow you can either use &lt;a href=&#34;#materialized-views&#34;&gt;materialized views&lt;/a&gt; or &lt;a href=&#34;#triggers&#34;&gt;triggers&lt;/a&gt; over calculation tables.&lt;/p&gt; &lt;p&gt;Materialized views are simpler to maintain but have &lt;a href=&#34;#disadvantages-of-a-materialized-view&#34;&gt;some disadvantages&lt;/a&gt; such as outdated data or unneeded processing of data. If you need totally current information or if you don&#39;t want to periodically do the calculations on all the rows then triggers are probably the better solution.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/postgres/#drop-all-tables-of-a-database&#34;&gt;Drop all tables of a database.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;drop&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;schema&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;cascade&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;create&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;schema&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/postgres/#views&#34;&gt;Views.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;A view is a named query stored in the PostgreSQL database server. A view is defined based on one or more tables which are known as base tables, and the query that defines the view is referred to as a defining query.&lt;/p&gt; &lt;p&gt;After creating a view, you can query data from it as you would from a regular table. Behind the scenes, PostgreSQL will rewrite the query against the view and its defining query, executing it to retrieve data from the base tables.&lt;/p&gt; &lt;p&gt;Views do not store data except the &lt;a href=&#34;#materialized-views&#34;&gt;materialized views&lt;/a&gt;. In PostgreSQL, you can create special views called materialized views that store data physically and periodically refresh it from the base tables.&lt;/p&gt; &lt;p&gt;Simple views can be &lt;a href=&#34;https://www.postgresqltutorial.com/postgresql-views/postgresql-updatable-views/&#34;&gt;updatable&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.postgresqltutorial.com/postgresql-views/&#34;&gt;Advantages of views&lt;/a&gt;&lt;/strong&gt; - Simplifying complex queries: Views help simplify complex queries. Instead of dealing with joins, aggregations, or filtering conditions, you can query from views as if they were regular tables.&lt;/p&gt; &lt;p&gt;Typically, first, you create views based on complex queries and store them in the database. Then, you can use simple queries based on views instead of using complex queries.&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Logical data independence: If your applications use views, you can freely modify the structure of the base tables. In other words, views enable you to create a layer of abstraction over the underlying tables.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Security and access control: Views enable fine-grained control over data access. You can create views that expose subsets of data in the base tables, hiding sensitive information.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;This is particularly useful when you have applications that require access to distinct portions of the data.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.postgresqltutorial.com/postgresql-views/managing-postgresql-views/&#34;&gt;Creating a view&lt;/a&gt;&lt;/strong&gt; In PostgreSQL, a view is a named query stored in the database server. To create a new view, you can use the &lt;code&gt;CREATE VIEW&lt;/code&gt; statement.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;VIEW&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;view_name&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;In this syntax:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Specify the name of the view after the &lt;code&gt;CREATE VIEW&lt;/code&gt; keywords.&lt;/li&gt; &lt;li&gt;Specify a &lt;code&gt;SELECT&lt;/code&gt; statement (query) that defines the view. The query is often referred to as the defining query of the view.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Creating a view examples&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;We’ll use the customer table from the &lt;a href=&#34;https://www.postgresqltutorial.com/postgresql-getting-started/postgresql-sample-database/&#34;&gt;sample database&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;&lt;em&gt;Basic CREATE VIEW statement example&lt;/em&gt;&lt;/p&gt; &lt;p&gt;The following example uses the CREATE VIEW statement to create a view based on the customer table:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;VIEW&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;contact&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;first_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;last_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;email&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;customer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Output:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;CREATE VIEW
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The following query data from the contact view:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;contact&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Output:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt; first_name  |  last_name   |                  email
-------------+--------------+------------------------------------------
 Jared       | Ely          | jared.ely@sakilacustomer.org
 Mary        | Smith        | mary.smith@sakilacustomer.org
 Patricia    | Johnson      | patricia.johnson@sakilacustomer.org
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;em&gt;Using the CREATE VIEW statement to create a view based on a complex query&lt;/em&gt;&lt;/p&gt; &lt;p&gt;The following example creates a view based on the tables customer, address, city, and country:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;VIEW&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;customer_info&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;first_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;last_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;email&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;phone&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;city&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;postal_code&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;country&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;customer&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INNER&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;JOIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;address&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;USING&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;address_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INNER&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;JOIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;city&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;USING&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;city_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INNER&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;JOIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;country&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;USING&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;country_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The following query retrieves data from the &lt;code&gt;customer_info&lt;/code&gt; view:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;customer_info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Output:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt; first_name  |  last_name   |                  email                   |    phone     |            city            | postal_code |                country
-------------+--------------+------------------------------------------+--------------+----------------------------+-------------+---------------------------------------
 Jared       | Ely          | jared.ely@sakilacustomer.org             | 35533115997  | Purwakarta                 | 25972       | Indonesia
 Mary        | Smith        | mary.smith@sakilacustomer.org            | 28303384290  | Sasebo                     | 35200       | Japan
 Patricia    | Johnson      | patricia.johnson@sakilacustomer.org      | 838635286649 | San Bernardino             | 17886       | United States
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Creating a view based on another view&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The following statement creates a view called &lt;code&gt;customer_usa&lt;/code&gt; based on the &lt;code&gt;customer_info&lt;/code&gt; view. The &lt;code&gt;customer_usa&lt;/code&gt; returns the customers who are in the United States:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;VIEW&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;customer_usa&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;customer_info&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;WHERE&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;country&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;United States&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Here’s the query that retrieves data from the customer_usa view:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;customer_usa&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Output:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt; first_name | last_name  |                email                 |    phone     |          city           | postal_code |    country
------------+------------+--------------------------------------+--------------+-------------------------+-------------+---------------
 Zachary    | Hite       | zachary.hite@sakilacustomer.org      | 191958435142 | Akron                   | 88749       | United States
 Richard    | Mccrary    | richard.mccrary@sakilacustomer.org   | 262088367001 | Arlington               | 42141       | United States
 Diana      | Alexander  | diana.alexander@sakilacustomer.org   | 6171054059   | Augusta-Richmond County | 30695       | United States
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Replacing a view&lt;/strong&gt; Note: for simple changes check &lt;a href=&#34;#alter-views&#34;&gt;alter views&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To change the defining query of a view, you use the &lt;code&gt;CREATE OR REPLACE VIEW&lt;/code&gt; statement:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;OR&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;REPLACE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;VIEW&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;view_name&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;In this syntax, you add the &lt;code&gt;OR REPLACE&lt;/code&gt; between the &lt;code&gt;CREATE&lt;/code&gt; and &lt;code&gt;VIEW&lt;/code&gt; keywords. If the view already exists, the statement replaces the existing view; otherwise, it creates a new view.&lt;/p&gt; &lt;p&gt;For example, the following statement changes the defining query of the contact view to include the phone information from the address table:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;OR&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;REPLACE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;VIEW&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;contact&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;first_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;last_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;email&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;phone&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;customer&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;INNER&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;JOIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;address&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;USING&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;address_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Display a view on psql&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To display a view on &lt;code&gt;psql&lt;/code&gt;, you follow these steps:&lt;/p&gt; &lt;p&gt;First, open the Command Prompt on Windows or Terminal on Unix-like systems and connect to the PostgreSQL server:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;psql&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-U&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;postgres
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Second, change the current database to &lt;code&gt;dvdrental&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;err&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dvdrental&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Third, display the view information using the &lt;code&gt;\d+ view_name&lt;/code&gt; command. For example, the following shows the contact view:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;err&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;contact&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Output:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;                                    View &#34;public.contact&#34;
   Column   |         Type          | Collation | Nullable | Default | Storage  | Description
------------+-----------------------+-----------+----------+---------+----------+-------------
 first_name | character varying(45) |           |          |         | extended |
 last_name  | character varying(45) |           |          |         | extended |
 email      | character varying(50) |           |          |         | extended |
 phone      | character varying(20) |           |          |         | extended |
View definition:
 SELECT customer.first_name,
    customer.last_name,
    customer.email,
    address.phone
   FROM customer
     JOIN address USING (address_id);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.postgresqltutorial.com/postgresql-views/postgresql-updatable-views/&#34;&gt;Updatable views&lt;/a&gt;&lt;/strong&gt; &lt;strong&gt;&lt;a href=&#34;https://www.postgresqltutorial.com/postgresql-views/postgresql-recursive-view/&#34;&gt;Recursive views&lt;/a&gt;&lt;/strong&gt; &lt;strong&gt;&lt;a href=&#34;https://www.postgresqltutorial.com/postgresql-views/postgresql-alter-view/&#34;&gt;Alter views&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/postgres/#materialized-views&#34;&gt;Materialized Views.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;PostgreSQL extends the view concept to the next level which allows views to store data physically. These views are called materialized views.&lt;/p&gt; &lt;p&gt;Materialized views cache the result set of an expensive query and allow you to refresh data periodically.&lt;/p&gt; &lt;p&gt;The materialized views can be useful in many cases that require fast data access. Therefore, you often find them in data warehouses and business intelligence applications.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.databasestar.com/sql-views/#Benefits_of_a_Materialized_View&#34;&gt;Benefits of materialized views&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Improve query efficiency: If a query takes a long time to run, it could be because there are a lot of transformations being done to the data: subqueries, functions, and joins, for example.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;A materialized view can combine all of that into a single result set that’s stored like a table.&lt;/p&gt; &lt;p&gt;This means that any user or application that needs to get this data can just query the materialized view itself, as though all of the data is in the one table, rather than running the expensive query that uses joins, functions, or subqueries.&lt;/p&gt; &lt;p&gt;Calculations can also be added to materialized views for any fields you may need, which can save time, and are often not stored in the database.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Simplify a query: Like a regular view, a materialized view can also be used to simplify a query. If a query is using a lot of logic such as joins and functions, using a materialized view can help remove some of that logic and place it into the materialized view.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.databasestar.com/sql-views/#Benefits_of_a_Materialized_View&#34;&gt;Disadvantages of a Materialized View&lt;/a&gt;&lt;/strong&gt; - Updates to data need to be set up: The main disadvantage to using materialized views is that the data needs to be refreshed.&lt;/p&gt; &lt;p&gt;The data that’s used to populate the materialized view is stored in the database tables. These tables can have their data updated, inserted, or deleted. When that happens, the data in the materialized view needs to be updated.&lt;/p&gt; &lt;p&gt;This can be done manually, but it should be done automatically.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://wiki.postgresql.org/wiki/Incremental_View_Maintenance&#34;&gt;Incremental updates are not supported&lt;/a&gt;: So the whole view is generated on each refresh.&lt;/li&gt; &lt;li&gt;Data may be inconsistent: Because the data is stored separately in the materialized view, the data in the materialized view may be inconsistent with the data in the underlying tables.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;This may be an issue if you are expecting or relying on data to be consistent.&lt;/p&gt; &lt;p&gt;However, for scenarios where it doesn’t matter (e.g. monthly reporting on months in the past), then it may be OK.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://medium.com/@ashkangoleh/unlocking-the-power-of-materialized-views-in-database-optimization-1fc670ba046ej&#34;&gt;Storage Requirements&lt;/a&gt;: Materialized Views can consume significant storage space, depending on the size of your dataset. This consideration is crucial, especially in resource-limited environments.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Creating materialized views&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To create a materialized view, you use the CREATE MATERIALIZED VIEW statement as follows:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MATERIALIZED&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;VIEW&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;IF&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;NOT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;EXISTS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;view_name&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;query&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;WITH&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;NO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;DATA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;How it works.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;First, specify the &lt;code&gt;view_name&lt;/code&gt; after the &lt;code&gt;CREATE MATERIALIZED VIEW&lt;/code&gt; clause&lt;/li&gt; &lt;li&gt;Second, add the &lt;code&gt;query&lt;/code&gt; that retrieves data from the underlying tables after the &lt;code&gt;AS&lt;/code&gt; keyword.&lt;/li&gt; &lt;li&gt;Third, if you want to load data into the materialized view at the creation time, use the &lt;code&gt;WITH DATA&lt;/code&gt; option; otherwise, you use &lt;code&gt;WITH NO DATA&lt;/code&gt; option. If you use the &lt;code&gt;WITH NO DATA&lt;/code&gt; option, the view is flagged as unreadable. It means that you cannot query data from the view until you load data into it.&lt;/li&gt; &lt;li&gt;Finally, use the &lt;code&gt;IF NOT EXISTS&lt;/code&gt; option to conditionally create a view only if it does not exist.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Refreshing data for materialized views&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Postgresql will never refresh the data by it&#39;s own, you need to define the processes that will update it.&lt;/p&gt; &lt;p&gt;To load or update the data into a materialized view, you use the &lt;code&gt;REFRESH MATERIALIZED VIEW&lt;/code&gt; statement:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;REFRESH&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MATERIALIZED&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;VIEW&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;view_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;When you refresh data for a materialized view, PostgreSQL locks the underlying tables. Consequently, you will not be able to retrieve data from underlying tables while data is loading into the view.&lt;/p&gt; &lt;p&gt;To avoid this, you can use the &lt;code&gt;CONCURRENTLY&lt;/code&gt; option.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;REFRESH&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MATERIALIZED&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;VIEW&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CONCURRENTLY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;view_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;With the &lt;code&gt;CONCURRENTLY&lt;/code&gt; option, PostgreSQL creates a temporary updated version of the materialized view, compares two versions, and performs &lt;code&gt;INSERT&lt;/code&gt; and &lt;code&gt;UPDATE&lt;/code&gt; only the differences.&lt;/p&gt; &lt;p&gt;PostgreSQL allows you to retrieve data from a materialized view while it is being updated. One requirement for using &lt;code&gt;CONCURRENTLY&lt;/code&gt; option is that the materialized view must have a &lt;code&gt;UNIQUE&lt;/code&gt; index.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://stackoverflow.com/questions/29437650/how-can-i-ensure-that-a-materialized-view-is-always-up-to-date&#34;&gt;Automatic update of materialized views&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Removing materialized views&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To remove a materialized view, you use the &lt;code&gt;DROP MATERIALIZED VIEW&lt;/code&gt; statement:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;DROP&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MATERIALIZED&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;VIEW&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;view_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;In this syntax, you specify the name of the materialized view that you want to drop after the &lt;code&gt;DROP MATERIALIZED VIEW&lt;/code&gt; keywords.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.postgresqltutorial.com/postgresql-views/postgresql-materialized-views/&#34;&gt;Materialized view example&lt;/a&gt;&lt;/strong&gt; We’ll use the tables in the &lt;a href=&#34;https://www.postgresqltutorial.com/postgresql-getting-started/postgresql-sample-database/&#34;&gt;sample database&lt;/a&gt; for creating a materialized view.&lt;/p&gt; &lt;p&gt;First, create a materialized view named &lt;code&gt;rental_by_category&lt;/code&gt; using the &lt;code&gt;CREATE MATERIALIZED VIEW&lt;/code&gt; statement:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MATERIALIZED&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;VIEW&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rental_by_category&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;category&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;sum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;amount&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;total_sales&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(((((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;payment&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;JOIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rental&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rental_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rental_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;JOIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inventory&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inventory_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inventory_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;JOIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;film&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;film_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;film_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;JOIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;film_category&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fc&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;film_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;film_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;JOIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;category&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;category_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;category_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;GROUP&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ORDER&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;sum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;amount&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;DESC&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;WITH&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;NO&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;DATA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Because of the &lt;code&gt;WITH NO DATA&lt;/code&gt; option, you cannot query data from the view. If you attempt to do so, you’ll get the following error message:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rental_by_category&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Output:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[Err] ERROR: materialized view &#34;rental_by_category&#34; has not been populated
HINT: Use the REFRESH MATERIALIZED VIEW command.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;PostgreSQL is helpful to give you a hint to ask for loading data into the view.&lt;/p&gt; &lt;p&gt;Second, load data into the materialized view using the &lt;code&gt;REFRESH MATERIALIZED VIEW&lt;/code&gt; statement:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;REFRESH&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MATERIALIZED&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;VIEW&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rental_by_category&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Third, retrieve data from the materialized view:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rental_by_category&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Output:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt; category   | total_sales
-------------+-------------
 Sports      |     4892.19
 Sci-Fi      |     4336.01
 Animation   |     4245.31
 Drama       |     4118.46
 Comedy      |     4002.48
 New         |     3966.38
 Action      |     3951.84
 Foreign     |     3934.47
 Games       |     3922.18
 Family      |     3830.15
 Documentary |     3749.65
 Horror      |     3401.27
 Classics    |     3353.38
 Children    |     3309.39
 Travel      |     3227.36
 Music       |     3071.52
(16 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;From now on, you can refresh the data in the &lt;code&gt;rental_by_category&lt;/code&gt; view using the &lt;code&gt;REFRESH MATERIALIZED VIEW&lt;/code&gt; statement.&lt;/p&gt; &lt;p&gt;However, to refresh it with &lt;code&gt;CONCURRENTLY&lt;/code&gt; option, you need to create a &lt;code&gt;UNIQUE&lt;/code&gt; index for the view first.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;UNIQUE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INDEX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rental_category&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rental_by_category&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;category&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Let’s refresh data concurrently for the &lt;code&gt;rental_by_category&lt;/code&gt; view.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;REFRESH&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MATERIALIZED&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;VIEW&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CONCURRENTLY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rental_by_category&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;hardware&#34;&gt;Hardware&lt;/h3&gt; &lt;h4 id=&#34;ecc-ram&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/rasdaemon/&#34;&gt;ECC RAM&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce ECC RAM.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.memtest86.com/ecc.htm&#34;&gt;Error Correction Code&lt;/a&gt; (ECC) is a mechanism used to detect and correct errors in memory data due to environmental interference and physical defects. ECC memory is used in high-reliability applications that cannot tolerate failure due to corrupted data.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;: Due to additional circuitry required for ECC protection, specialized ECC hardware support is required by the CPU chipset, motherboard and DRAM module. This includes the following:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Server-grade CPU chipset with ECC support (Intel Xeon, AMD Ryzen)&lt;/li&gt; &lt;li&gt;Motherboard supporting ECC operation&lt;/li&gt; &lt;li&gt;ECC RAM&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Consult the motherboard and/or CPU documentation for the specific model to verify whether the hardware supports ECC. Use vendor-supplied list of certified ECC RAM, if provided.&lt;/p&gt; &lt;p&gt;Most ECC-supported motherboards allow you to configure ECC settings from the BIOS setup. They are usually on the Advanced tab. The specific option depends on the motherboard vendor or model such as the following:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;DRAM ECC Enable (American Megatrends, ASUS, ASRock, MSI)&lt;/li&gt; &lt;li&gt;ECC Mode (ASUS)&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Monitorization&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The mechanism for how ECC errors are logged and reported to the end-user depends on the BIOS and operating system. In most cases, corrected ECC errors are written to system/event logs. Uncorrected ECC errors may result in kernel panic or blue screen.&lt;/p&gt; &lt;p&gt;The Linux kernel supports reporting ECC errors for ECC memory via the EDAC (Error Detection And Correction) driver subsystem. Depending on the Linux distribution, ECC errors may be reported by the following:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/rasdaemon/&#34;&gt;&lt;code&gt;rasdaemon&lt;/code&gt;&lt;/a&gt;: monitor ECC memory and report both correctable and uncorrectable memory errors on recent Linux kernels.&lt;/li&gt; &lt;li&gt;&lt;code&gt;mcelog&lt;/code&gt; (Deprecated): collects and decodes MCA error events on x86.&lt;/li&gt; &lt;li&gt;&lt;code&gt;edac-utils&lt;/code&gt; (Deprecated): fills DIMM labels data and summarizes memory errors.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;To configure rasdaemon follow &lt;a href=&#34;https://lyz-code.github.io/blue-book/rasdaemon/&#34;&gt;this article&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Confusion on boards supporting ECC&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;I&#39;ve read that even if some motherboards say that they &#34;Support ECC&#34; some of them don&#39;t do anything with it.&lt;/p&gt; &lt;p&gt;On &lt;a href=&#34;https://forums.servethehome.com/index.php?threads/has-anyone-gotten-ecc-logging-rasdaemon-edac-whea-etc-to-work-on-xeon-w-1200-or-w-1300-or-core-12-or-13-gen-processors.39257/&#34;&gt;this post&lt;/a&gt; and the &lt;a href=&#34;https://www.kernel.org/doc/html/latest/firmware-guide/acpi/apei/einj.html&#34;&gt;kernel docs&lt;/a&gt; show that you should see references to ACPI/WHEA in the specs manual. Ideally ACPI5 support.&lt;/p&gt; &lt;p&gt;From the ) EINJ provides a hardware error injection mechanism. It is very useful for debugging and testing APEI and RAS features in general.&lt;/p&gt; &lt;p&gt;You need to check whether your BIOS supports EINJ first. For that, look for early boot messages similar to this one:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ACPI: EINJ 0x000000007370A000 000150 (v01 INTEL           00000001 INTL 00000001)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Which shows that the BIOS is exposing an EINJ table - it is the mechanism through which the injection is done.&lt;/p&gt; &lt;p&gt;Alternatively, look in &lt;code&gt;/sys/firmware/acpi/tables&lt;/code&gt; for an &#34;EINJ&#34; file, which is a different representation of the same thing.&lt;/p&gt; &lt;p&gt;It doesn&#39;t necessarily mean that EINJ is not supported if those above don&#39;t exist: before you give up, go into BIOS setup to see if the BIOS has an option to enable error injection. Look for something called &lt;code&gt;WHEA&lt;/code&gt; or similar. Often, you need to enable an &lt;code&gt;ACPI5&lt;/code&gt; support option prior, in order to see the &lt;code&gt;APEI&lt;/code&gt;,&lt;code&gt;EINJ&lt;/code&gt;,... functionality supported and exposed by the BIOS menu.&lt;/p&gt; &lt;p&gt;To use &lt;code&gt;EINJ&lt;/code&gt;, make sure the following are options enabled in your kernel configuration:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;CONFIG_DEBUG_FS
CONFIG_ACPI_APEI
CONFIG_ACPI_APEI_EINJ
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;One way to test it can be to run &lt;a href=&#34;https://lyz-code.github.io/blue-book/memtest/&#34;&gt;memtest&lt;/a&gt; as it sometimes &lt;a href=&#34;https://forum.level1techs.com/t/asrock-taichi-x570-ecc-options-no-longer-in-bios/178045&#34;&gt;shows ECC errors&lt;/a&gt; such as &lt;code&gt;** Warning** ECC injection may be disabled for AMD Ryzen (70h-7fh)&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Other people (&lt;a href=&#34;https://www.memtest86.com/ecc.htm&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;https://www.reddit.com/r/ASRock/comments/jlsw5z/x570_pro4_correctable_ecc_errors_no_response_from/&#34;&gt;2&lt;/a&gt; say that there are a lot of motherboards that NEVER report any corrected errors to the OS. In order to see corrected errors, PFEH (Platform First Error Handling) has to be disabled. On some motherboards and FW versions this setting is hidden from the user and always enabled, thus resulting in zero correctable errors getting reported.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.memtest86.com/ecc.htm&#34;&gt;They also suggest&lt;/a&gt; to disable &#34;Quick Boot&#34;. In order to initialize ECC, memory has to be written before it can be used. Usually this is done by BIOS, but with some motherboards this step is skipped if &#34;Quick Boot&#34; is enabled.&lt;/p&gt; &lt;p&gt;The people behind &lt;a href=&#34;https://lyz-code.github.io/blue-book/memtest/&#34;&gt;memtest&lt;/a&gt; have a &lt;a href=&#34;https://www.passmark.com/products/ecc-tester/index.php&#34;&gt;paid tool to test ECC&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce rasdaemon the ECC monitor.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/mchehab/rasdaemon&#34;&gt;&lt;code&gt;rasdaemon&lt;/code&gt;&lt;/a&gt; is a RAS (Reliability, Availability and Serviceability) logging tool. It records memory errors, using the EDAC tracing events. EDAC is a Linux kernel subsystem with handles detection of ECC errors from memory controllers for most chipsets on i386 and x86_64 architectures. EDAC drivers for other architectures like arm also exists.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rasdaemon
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;The output will be available via syslog but you can show it to the foreground (&lt;code&gt;-f&lt;/code&gt;) or to an sqlite3 database (&lt;code&gt;-r&lt;/code&gt;)&lt;/p&gt; &lt;p&gt;To post-process and decode received MCA errors on AMD SMCA systems, run:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;rasdaemon&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--status&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;STATUS_reg&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--ipid&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;IPID_reg&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--smca&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--family&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;CPU&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Family&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--model&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;CPU&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Model&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--bank&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;BANK_NUM&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Status and IPID Register values (in hex) are mandatory. The smca flag with family and model are required if not decoding locally. Bank parameter is optional.&lt;/p&gt; &lt;p&gt;You may also start it via systemd:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;start&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rasdaemon
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The rasdaemon will then output the messages to journald.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.setphaserstostun.org/posts/monitoring-ecc-memory-on-linux-with-rasdaemon/&#34;&gt;Usage&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;At this point &lt;code&gt;rasdaemon&lt;/code&gt; should already be running on your system. You can now use the &lt;code&gt;ras-mc-ctl&lt;/code&gt; tool to query the errors that have been detected. If everything is well configured you&#39;ll see something like:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ras-mc-ctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--error-count
Label&lt;span class=&#34;w&#34;&gt;                 &lt;/span&gt;CE&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;UE
mc#0csrow#2channel#0&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
mc#0csrow#2channel#1&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
mc#0csrow#3channel#1&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
mc#0csrow#3channel#0&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If it&#39;s not you&#39;ll see:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ras-mc-ctl:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Error:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;No&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;DIMMs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;found&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/sys&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;or&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;new&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sysfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;EDAC&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;interface&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;not&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;found.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The &lt;code&gt;CE&lt;/code&gt; column represents the number of corrected errors for a given DIMM, &lt;code&gt;UE&lt;/code&gt; represents uncorrectable errors that were detected. The label on the left shows the EDAC path under &lt;code&gt;/sys/devices/system/edac/mc/&lt;/code&gt; of every DIMM. This is not very readable, if you wish to improve the labeling &lt;a href=&#34;https://www.setphaserstostun.org/posts/monitoring-ecc-memory-on-linux-with-rasdaemon/&#34;&gt;read this article&lt;/a&gt;&lt;/p&gt; &lt;p&gt;More ways to check is to run:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ras-mc-ctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--status
ras-mc-ctl:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;drivers&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;are&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;loaded.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can also see a summary of the state with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ras-mc-ctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--summary
No&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Memory&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;errors.

No&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;PCIe&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AER&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;errors.

No&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Extlog&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;errors.

DBD::SQLite::db&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;prepare&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;failed:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;no&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;such&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;table:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;devlink_event&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;at&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/usr/sbin/ras-mc-ctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;line&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1183&lt;/span&gt;.
Can&lt;span class=&#34;err&#34;&gt;&#39;&lt;/span&gt;t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;call&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;method&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;execute&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;on&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;an&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;undefined&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;value&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;at&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/usr/sbin/ras-mc-ctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;line&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1184&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Monitorization&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can use &lt;a href=&#34;https://lyz-code.github.io/blue-book/loki/&#34;&gt;loki&lt;/a&gt; to monitor ECC errors shown in the logs with the next alerts:&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;groups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ecc&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ECCError&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;count_over_time({job=&#34;systemd-journal&#34;, unit=&#34;rasdaemon.service&#34;, level=&#34;error&#34;} [5m])  &amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;1m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;critical&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;Possible&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;ECC&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;detected&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ECCWarning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;count_over_time({job=&#34;systemd-journal&#34;, unit=&#34;rasdaemon.service&#34;, level=&#34;warning&#34;} [5m])  &amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;1m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;Possible&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;ECC&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;warning&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;detected&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ECCAlert&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;count_over_time({job=&#34;systemd-journal&#34;, unit=&#34;rasdaemon.service&#34;, level!~&#34;info|error|warning&#34;} [5m]) &amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;1m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;info&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;ECC&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;trace&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;unknown&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;detected&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/mchehab/rasdaemon&#34;&gt;Source&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Check if system is actually using ECC.&lt;/p&gt; &lt;p&gt;Another way is to run &lt;code&gt;dmidecode&lt;/code&gt;. For ECC support you&#39;ll see: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dmidecode&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;memory&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ECC
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Error&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Correction&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Type:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Single-bit&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ECC
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# or&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Error&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Correction&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Type:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Multi-bit&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ECC
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;No ECC:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dmidecode&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;memory&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ECC
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Error&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Correction&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Type:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;None
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can also test it with &lt;a href=&#34;https://lyz-code.github.io/blue-book/rasdaemon/&#34;&gt;&lt;code&gt;rasdaemon&lt;/code&gt;&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;gpu&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gpu/&#34;&gt;GPU&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce GPU.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Graphics_processing_unit&#34;&gt;GPU&lt;/a&gt; or Graphic Processing Unit is a specialized electronic circuit initially designed to accelerate computer graphics and image processing (either on a video card or embedded on motherboards, mobile phones, personal computers, workstations, and game consoles).&lt;/p&gt; &lt;p&gt;For years I&#39;ve wanted to buy a graphic card but I&#39;ve been stuck in the problem that I don&#39;t have a desktop. I have a X280 lenovo laptop used to work and personal use with an integrated card that has let me so far to play old games such as &lt;a href=&#34;https://lyz-code.github.io/blue-book/kag/&#34;&gt;King Arthur Gold&lt;/a&gt; or &lt;a href=&#34;https://lyz-code.github.io/blue-book/age_of_empires/&#34;&gt;Age of Empires II&lt;/a&gt;, but has hard times playing &#34;newer&#34; games such as It takes two. Last year I also bought a &lt;a href=&#34;https://lyz-code.github.io/blue-book/nas/&#34;&gt;NAS&lt;/a&gt; with awesome hardware. So it makes no sense to buy a desktop just for playing.&lt;/p&gt; &lt;p&gt;Now that I host &lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/&#34;&gt;Jellyfin&lt;/a&gt; on the NAS and that machine learning is on the hype with a lot of interesting solutions that can be self-hosted (whisper, chatgpt similar solutions...), it starts to make sense to add a GPU to the server. What made me give the step is that you can also self-host a gaming server to stream to any device! It makes so much sense to have all the big guns inside the NAS and stream the content to the less powerful devices.&lt;/p&gt; &lt;p&gt;That way if you host services, you make the most use of the hardware.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gpu/#install-cuda&#34;&gt;Install cuda.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html&#34;&gt;CUDA&lt;/a&gt; is a parallel computing platform and programming model invented by NVIDIA®. It enables dramatic increases in computing performance by harnessing the power of the graphics processing unit (GPU). If you&#39;re not using Debian 11 follow &lt;a href=&#34;https://developer.nvidia.com/cuda-downloads&#34;&gt;these instructions&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Base Installer&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;wget&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://developer.download.nvidia.com/compute/cuda/12.5.1/local_installers/cuda-repo-debian11-12-5-local_12.5.1-555.42.06-1_amd64.deb
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dpkg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cuda-repo-debian11-12-5-local_12.5.1-555.42.06-1_amd64.deb
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/cuda-repo-debian11-12-5-local/cuda-*-keyring.gpg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/usr/share/keyrings/
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;add-apt-repository&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;contrib
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-y&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cuda-toolkit-12-5
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Additional installation options are detailed &lt;a href=&#34;https://developer.nvidia.com/cuda-downloads&#34;&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Driver Installer&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To install the open kernel module flavor:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-y&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;nvidia-kernel-open-dkms
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-y&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cuda-drivers
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Install cuda:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cuda
reboot
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Install nvidia card&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Check if your card is supported in the &lt;a href=&#34;https://wiki.debian.org/NvidiaGraphicsDrivers&#34;&gt;releases supported by your OS&lt;/a&gt; - &lt;a href=&#34;https://wiki.debian.org/NvidiaGraphicsDrivers&#34;&gt;If it&#39;s supported&lt;/a&gt; - &lt;a href=&#34;https://docs.kinetica.com/7.1/install/nvidia_deb/&#34;&gt;If it&#39;s not supported&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Ensure the GPUs are Installed&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Install &lt;code&gt;pciutils&lt;/code&gt;:&lt;/p&gt; &lt;p&gt;Ensure that the &lt;code&gt;lspci&lt;/code&gt; command is installed (which lists the PCI devices connected to the server):&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-y&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pciutils
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Check Installed Nvidia Cards: Perform a quick check to determine what Nvidia cards have been installed:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;lspci&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;VGA
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The output of the &lt;code&gt;lspci&lt;/code&gt; command above should be something similar to:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;00:02.0 VGA compatible controller: Intel Corporation 4th Gen ...
01:00.0 VGA compatible controller: Nvidia Corporation ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you do not see a line that includes Nvidia, then the GPU is not properly installed. Otherwise, you should see the make and model of the GPU devices that are installed.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Disable Nouveau&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Blacklist Nouveau in Modprobe: The &lt;code&gt;nouveau&lt;/code&gt; driver is an alternative to the Nvidia drivers generally installed on the server. It does not work with CUDA and must be disabled. The first step is to edit the file at &lt;code&gt;/etc/modprobe.d/blacklist-nouveau.conf&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Create the file with the following content:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;lt;&amp;lt;EOF | sudo tee /etc/modprobe.d/blacklist-nouveau.conf&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;blacklist nouveau&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;blacklist lbm-nouveau&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;options nouveau modeset=0&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;alias nouveau off&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;alias lbm-nouveau off&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;EOF&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then, run the following commands:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;options&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;nouveau&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;modeset&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tee&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/modprobe.d/nouveau-kms.conf
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update-initramfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-u
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Update Grub to Blacklist Nouveau:&lt;/p&gt; &lt;p&gt;Backup your grub config template:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/default/grub&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/default/grub.bak
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then, update your grub config template at &lt;code&gt;/etc/default/grub&lt;/code&gt;. Add &lt;code&gt;rd.driver.blacklist=nouveau&lt;/code&gt; and &lt;code&gt;rcutree.rcu_idle_gp_delay=1&lt;/code&gt; to the &lt;code&gt;GRUB_CMDLINE_LINUX&lt;/code&gt; variable. For example, change:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;GRUB_CMDLINE_LINUX&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;quiet&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;to:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;GRUB_CMDLINE_LINUX&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;quiet rd.driver.blacklist=nouveau rcutree.rcu_idle_gp_delay=1&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then, rebuild your grub config:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grub2-mkconfig&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/boot/grub/grub.cfg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Install prerequisites&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The following prerequisites should be installed before installing the Nvidia drivers:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-y&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;linux-headers-&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;uname&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;make&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;gcc-4.8
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-y&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;acpid&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dkms
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Close X Server:&lt;/p&gt; &lt;p&gt;Before running the install, you should exit out of any X environment, such as Gnome, KDE, or XFCE. To exit the X session, switch to a TTY console using &lt;code&gt;Ctrl-Alt-F1&lt;/code&gt; and then determine whether you are running &lt;code&gt;lightdm&lt;/code&gt; or &lt;code&gt;gdm&lt;/code&gt; by running:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ps&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;aux&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;lightdm|gdm|kdm&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Depending on which is running, stop the service, running the following commands (substitute &lt;code&gt;gdm&lt;/code&gt; or &lt;code&gt;kdm&lt;/code&gt; for &lt;code&gt;lightdm&lt;/code&gt; as appropriate):&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;service&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;lightdm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;stop
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;init&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Install Drivers Only:&lt;/p&gt; &lt;p&gt;To accommodate GL-accelerated rendering, OpenGL and GL Vendor Neutral Dispatch (GLVND) are now required and should be installed with the Nvidia drivers. OpenGL is an installation option in the &lt;code&gt;*.run&lt;/code&gt; type of drivers. In other types of the drivers, OpenGL is enabled by default in most modern versions (dated 2016 and later). GLVND can be installed using the installer menus or via the &lt;code&gt;--glvnd-glx-client&lt;/code&gt; command line flag.&lt;/p&gt; &lt;p&gt;This section deals with installing the drivers via the &lt;code&gt;*.run&lt;/code&gt; executables provided by Nvidia.&lt;/p&gt; &lt;p&gt;To download only the drivers, navigate to &lt;a href=&#34;http://www.nvidia.com/object/unix.html&#34;&gt;http://www.nvidia.com/object/unix.html&lt;/a&gt; and click the Latest Long Lived Branch version under the appropriate CPU architecture. On the ensuing page, click Download and then click Agree and Download on the page that follows.&lt;/p&gt; &lt;p&gt;The Unix drivers found in the link above are also compatible with all Nvidia Tesla models.&lt;/p&gt; &lt;p&gt;If you&#39;d prefer to download the full driver repository, Nvidia provides a tool to recommend the most recent available driver for your graphics card at &lt;a href=&#34;http://www.Nvidia.com/Download/index.aspx?lang=en-us&#34;&gt;http://www.Nvidia.com/Download/index.aspx?lang=en-us&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;If you are unsure which Nvidia devices are installed, the &lt;code&gt;lspci&lt;/code&gt; command should give you that information:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;lspci&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;nvidia&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Download the recommended driver executable. Change the file permissions to allow execution:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;chmod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;+x&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;./NVIDIA-Linux-&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;uname&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-m&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;-*.run
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Run the install.&lt;/p&gt; &lt;p&gt;To check that the GPU is well installed and functioning properly, you can use the &lt;code&gt;nvidia-smi&lt;/code&gt; command. This command provides detailed information about the installed Nvidia GPUs, including their status, utilization, and driver version.&lt;/p&gt; &lt;p&gt;First, ensure the Nvidia drivers are installed. Then, run:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;nvidia-smi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If the GPU is properly installed, you should see an output that includes information about the GPU, such as its model, memory usage, and driver version. The output will look something like this:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;+-----------------------------------------------------------------------------+
| NVIDIA-SMI 450.66       Driver Version: 450.66       CUDA Version: 11.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  Tesla K80           Off  | 00000000:00:1E.0 Off |                    0 |
| N/A   38C    P8    29W / 149W |      0MiB / 11441MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you encounter any errors or the GPU is not listed, there may be an issue with the installation or configuration of the GPU drivers.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://askubuntu.com/questions/387594/how-to-measure-gpu-usage&#34;&gt;Measure usage&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;For Nvidia GPUs there is a tool &lt;a href=&#34;https://developer.nvidia.com/system-management-interface&#34;&gt;nvidia-smi&lt;/a&gt; that can show memory usage, GPU utilization and temperature of GPU.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/wilicc/gpu-burn&#34;&gt;Load test the gpu&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;First make sure you have &lt;a href=&#34;#install-cuda&#34;&gt;CUDA&lt;/a&gt; installed, then install the &lt;code&gt;gpu_burn&lt;/code&gt; tool &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;clone&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://github.com/wilicc/gpu-burn
&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;gpu-burn
make
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;To run a test for 60 seconds run: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;./gpu_burn&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;60&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://developer.nvidia.com/blog/monitoring-gpus-in-kubernetes-with-dcgm/&#34;&gt;Monitor it with Prometheus&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://developer.nvidia.com/dcgm&#34;&gt;NVIDIA DCGM&lt;/a&gt; is a set of tools for managing and monitoring NVIDIA GPUs in large-scale, Linux-based cluster environments. It’s a low overhead tool that can perform a variety of functions including active health monitoring, diagnostics, system validation, policies, power and clock management, group configuration, and accounting. For more information, see the &lt;a href=&#34;https://docs.nvidia.com/datacenter/dcgm/latest/dcgm-user-guide/overview.html&#34;&gt;DCGM User Guide&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;You can use DCGM to expose GPU metrics to Prometheus using &lt;code&gt;dcgm-exporter&lt;/code&gt;.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/NVIDIA/nvidia-container-toolkit&#34;&gt;Install NVIDIA Container Kit&lt;/a&gt;: The NVIDIA Container Toolkit allows users to build and run GPU accelerated containers. The toolkit includes a container runtime library and utilities to automatically configure containers to leverage NVIDIA GPUs.&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-y&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;nvidia-container-toolkit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Configure the container runtime by using the nvidia-ctk command:&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;nvidia-ctk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;runtime&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;configure&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--runtime&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;docker
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; - Restart the Docker daemon:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;restart&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Install NVIDIA DCGM: Follow the &lt;a href=&#34;https://docs.nvidia.com/datacenter/dcgm/latest/user-guide/getting-started.html&#34;&gt;Getting Started Guide&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Determine the distribution name:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;distribution&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;.&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/os-release&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ID$VERSION_ID&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sed&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-e&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;s/\.//g&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Download the meta-package to set up the CUDA network repository:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;wget&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://developer.download.nvidia.com/compute/cuda/repos/&lt;span class=&#34;nv&#34;&gt;$distribution&lt;/span&gt;/x86_64/cuda-keyring_1.1-1_all.deb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Install the repository meta-data and the CUDA GPG key:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dpkg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cuda-keyring_1.1-1_all.deb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Update the Apt repository cache:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Now, install DCGM:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-y&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;datacenter-gpu-manager
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Enable the DCGM systemd service (on reboot) and start it now:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--now&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;enable&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;nvidia-dcgm
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You should see output similar to this:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;● dcgm.service - DCGM service
  Loaded: loaded (/usr/lib/systemd/system/dcgm.service; disabled; vendor preset: enabled)
  Active: active (running) since Mon 2020-10-12 12:18:57 PDT; 14s ago
Main PID: 32847 (nv-hostengine)
    Tasks: 7 (limit: 39321)
  CGroup: /system.slice/dcgm.service
          └─32847 /usr/bin/nv-hostengine -n

Oct 12 12:18:57 ubuntu1804 systemd[1]: Started DCGM service.
Oct 12 12:18:58 ubuntu1804 nv-hostengine[32847]: DCGM initialized
Oct 12 12:18:58 ubuntu1804 nv-hostengine[32847]: Host Engine Listener Started
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To verify installation, use &lt;code&gt;dcgmi&lt;/code&gt; to query the system. You should see a listing of all supported GPUs (and any NVSwitches) found in the system:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;dcgmi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;discovery&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Output:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;8 GPUs found.
+--------+----------------------------------------------------------------------+
| GPU ID | Device Information                                                   |
+--------+----------------------------------------------------------------------+
| 0      | Name: A100-SXM4-40GB                                                 |
|        | PCI Bus ID: 00000000:07:00.0                                         |
|        | Device UUID: GPU-1d82f4df-3cf9-150d-088b-52f18f8654e1                |
+--------+----------------------------------------------------------------------+
| 1      | Name: A100-SXM4-40GB                                                 |
|        | PCI Bus ID: 00000000:0F:00.0                                         |
|        | Device UUID: GPU-94168100-c5d5-1c05-9005-26953dd598e7                |
+--------+----------------------------------------------------------------------+
| 2      | Name: A100-SXM4-40GB                                                 |
|        | PCI Bus ID: 00000000:47:00.0                                         |
|        | Device UUID: GPU-9387e4b3-3640-0064-6b80-5ace1ee535f6                |
+--------+----------------------------------------------------------------------+
| 3      | Name: A100-SXM4-40GB                                                 |
|        | PCI Bus ID: 00000000:4E:00.0                                         |
|        | Device UUID: GPU-cefd0e59-c486-c12f-418c-84ccd7a12bb2                |
+--------+----------------------------------------------------------------------+
| 4      | Name: A100-SXM4-40GB                                                 |
|        | PCI Bus ID: 00000000:87:00.0                                         |
|        | Device UUID: GPU-1501b26d-f3e4-8501-421d-5a444b17eda8                |
+--------+----------------------------------------------------------------------+
| 5      | Name: A100-SXM4-40GB                                                 |
|        | PCI Bus ID: 00000000:90:00.0                                         |
|        | Device UUID: GPU-f4180a63-1978-6c56-9903-ca5aac8af020                |
+--------+----------------------------------------------------------------------+
| 6      | Name: A100-SXM4-40GB                                                 |
|        | PCI Bus ID: 00000000:B7:00.0                                         |
|        | Device UUID: GPU-8b354e3e-0145-6cfc-aec6-db2c28dae134                |
+--------+----------------------------------------------------------------------+
| 7      | Name: A100-SXM4-40GB                                                 |
|        | PCI Bus ID: 00000000:BD:00.0                                         |
|        | Device UUID: GPU-a16e3b98-8be2-6a0c-7fac-9cb024dbc2df                |
+--------+----------------------------------------------------------------------+
6 NvSwitches found.
+-----------+
| Switch ID |
+-----------+
| 11        |
| 10        |
| 13        |
| 9         |
| 12        |
| 8         |
+-----------+
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/NVIDIA/dcgm-exporter&#34;&gt;Install the dcgm-exporter&lt;/a&gt;&lt;/p&gt; &lt;p&gt;As it doesn&#39;t need any persistence I&#39;ve added it to the prometheus docker compose:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;  dcgm-exporter:
    # latest didn&#39;t work
    image: nvcr.io/nvidia/k8s/dcgm-exporter:3.3.6-3.4.2-ubuntu22.04
    deploy:
      resources:
        reservations:
          devices:
            - capabilities: [gpu]
    restart: unless-stopped
    container_name: dcgm-exporter
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;And added the next scraping config in &lt;code&gt;prometheus.yml&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;job_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;dcgm-exporter&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metrics_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/metrics&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;static_configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;targets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;dcgm-exporter:9400&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Adding alerts&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Tweak the next alerts for your use case.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;groups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;dcgm-alerts&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;GPUHighTemperature&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;DCGM_FI_DEV_GPU_TEMP &amp;gt; 80&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;5m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;critical&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;GPU&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;High&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Temperature&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;GPU&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;temperature&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;above&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;80°C&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;more&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;than&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;minutes.\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;GPUMemoryUtilizationHigh&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;DCGM_FI_DEV_MEM_COPY_UTIL &amp;gt; 90&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;10m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;GPU&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Memory&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Utilization&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;High&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;GPU&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;memory&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;utilization&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;above&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;90%&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;more&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;than&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;minutes.\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;GPUComputeUtilizationHigh&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;DCGM_FI_DEV_GPU_UTIL &amp;gt; 90&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;10m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;GPU&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Compute&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Utilization&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;High&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;GPU&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;compute&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;utilization&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;above&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;90%&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;more&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;than&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;minutes.\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;GPUPowerUsageHigh&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;DCGM_FI_DEV_POWER_USAGE &amp;gt; 160&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;5m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;GPU&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Power&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Usage&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;High&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;GPU&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;power&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;usage&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;above&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;160W&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;more&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;than&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;minutes.\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;GPUUnavailable&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;up{job=&#34;dcgm-exporter&#34;} == 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;5m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;critical&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;GPU&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Unavailable&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;DCGM&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Exporter&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;down&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;or&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;unreachable&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;more&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;than&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;minutes.\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Adding a dashboard&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;I&#39;ve &lt;a href=&#34;https://grafana.com/grafana/dashboards/12239-nvidia-dcgm-exporter-dashboard/&#34;&gt;tweaked this dashboard&lt;/a&gt; to simplify it. Check the article for the full json&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;operating-systems&#34;&gt;Operating Systems&lt;/h2&gt; &lt;h3 id=&#34;linux&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/&#34;&gt;Linux&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/#linux-loki-alerts&#34;&gt;Linux loki alerts.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;TooManyLogs&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;sum by(hostname) (count_over_time({job=&#34;systemd-journal&#34;} [1d])) / sum by(hostname) (count_over_time({job=&#34;systemd-journal&#34;} [1d] offset 1d)) &amp;gt; 1.5&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;server&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname}}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;generating&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;too&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;many&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;logs&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;TooFewLogs&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;sum by(hostname) (count_over_time({job=&#34;systemd-journal&#34;} [1d])) / sum by(hostname) (count_over_time({job=&#34;systemd-journal&#34;} [1d] offset 1d)) &amp;lt; 0.5&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;server&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname}}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;generating&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;too&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;few&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;logs&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;linux-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/&#34;&gt;Linux Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#makefile-use-bash-instead-of-sh&#34;&gt;Makefile use bash instead of sh.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The program used as the shell is taken from the variable &lt;code&gt;SHELL&lt;/code&gt;. If this variable is not set in your makefile, the program &lt;code&gt;/bin/sh&lt;/code&gt; is used as the shell.&lt;/p&gt; &lt;p&gt;So put &lt;code&gt;SHELL := /bin/bash&lt;/code&gt; at the top of your makefile, and you should be good to go.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#recover-the-message-of-a-commit-if-the-command-failed&#34;&gt;Recover the message of a commit if the command failed.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;git commit&lt;/code&gt; can fail for reasons such as &lt;code&gt;gpg.commitsign = true&lt;/code&gt; &amp;amp;&amp;amp; &lt;code&gt;gpg&lt;/code&gt; fails, or when running a pre-commit. Retrying the command opens a blank editor and the message seems to be lost.&lt;/p&gt; &lt;p&gt;The message is saved though in &lt;code&gt;.git/COMMIT_EDITMSG&lt;/code&gt;, so you can:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;commit&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-m&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.git/COMMIT_EDITMSG&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Or in general (suitable for an alias for example):&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;commit&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-m&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rev-parse&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--git-dir&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/COMMIT_EDITMSG)&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#configure-nginx-to-restrict-methods&#34;&gt;Configure nginx to restrict methods.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;server {
    listen 80;
    server_name yourdomain.com;

    location / {
        if ($request_method !~ ^(GET|POST)$ ) {
            return 405;
        }

        try_files $uri $uri/ =404;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#configure-nginx-location-regexp-to-accept-dashes&#34;&gt;Configure nginx location regexp to accept dashes.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;location ~* /share/[\w-]+ {
  root /home/project_root;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#configure-nginx-location-to-accept-many-paths&#34;&gt;Configure nginx location to accept many paths.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;location ~ ^/(static|media)/ {
  root /home/project_root;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#remove-image-metadata&#34;&gt;Remove image metadata.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;exiftool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-all:all&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/path/to/file
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#get-the-size-increment-of-a-directory-between-two-dates&#34;&gt;Get the size increment of a directory between two dates.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To see how much has a directory grown between two dates you can use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;find&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/path/to/directory&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-type&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-newerat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2022&lt;/span&gt;-12-31&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;!&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-newerat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2024&lt;/span&gt;-01-01&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-printf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;%s\\n&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;awk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;{s+=$1} END {print s}&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;It finds all the files in that directory that were created in the 2023, it only prints their size in bytes and then it adds them all up.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce detox.&lt;/p&gt; &lt;p&gt;detox cleans up filenames from the command line.&lt;/p&gt; &lt;p&gt;Installation:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;detox
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Usage:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;detox&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;*
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#rotate-image-with-the-command-line-&#34;&gt;Rotate image with the command line.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you want to overwrite in-place, &lt;code&gt;mogrify&lt;/code&gt; from the ImageMagick suite seems to be the easiest way to achieve this:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mogrify&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-rotate&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-90&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;*.jpg

mogrify&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-rotate&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;90&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;*.jpg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#configure-desktop-icons-in-gnome&#34;&gt;Configure desktop icons in gnome.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Latest versions of gnome dont have desktop icons &lt;a href=&#34;https://gitlab.gnome.org/GNOME/nautilus/-/issues/158#instructions&#34;&gt;read this article to fix this&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#send-multiline-messages-with-notify-send&#34;&gt;Send multiline messages with notify-send.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The title can&#39;t have new lines, but the body can.&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;notify-send&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Title&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;This is the first line.\nAnd this is the second.&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; feat(linux_snippets#Find BIOS version): Find BIOS version&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;dmidecode&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;less
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#reboot-server-on-kernel-panic-&#34;&gt;Reboot server on kernel panic.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The &lt;code&gt;proc/sys/kernel/panic&lt;/code&gt; file gives read/write access to the kernel variable &lt;code&gt;panic_timeout&lt;/code&gt;. If this is zero, the kernel will loop on a panic; if nonzero it indicates that the kernel should autoreboot after this number of seconds. When you use the software watchdog device driver, the recommended setting is &lt;code&gt;60&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;To set the value add the next contents to the &lt;code&gt;/etc/sysctl.d/99-panic.conf&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kernel.panic = 60
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Or with an ansible task:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Configure reboot on kernel panic&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;become&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;lineinfile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/etc/sysctl.d/99-panic.conf&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;line&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;kernel.panic = 60&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;create&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;state&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;present&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#share-a-calculated-value-between-github-actions-steps&#34;&gt;Share a calculated value between github actions steps.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You need to set a step&#39;s output parameter. Note that the step will need an &lt;code&gt;id&lt;/code&gt; to be defined to later retrieve the output value.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;{name}={value}&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$GITHUB_OUTPUT&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Set color&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;color-selector&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;echo &#34;SELECTED_COLOR=green&#34; &amp;gt;&amp;gt; &#34;$GITHUB_OUTPUT&#34;&lt;/span&gt;
&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Get color&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;env&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;SELECTED_COLOR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;${{ steps.color-selector.outputs.SELECTED_COLOR }}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;echo &#34;The selected color is $SELECTED_COLOR&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#split-a-zip-into-sizes-with-restricted-size-&#34;&gt;Split a zip into sizes with restricted size.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Something like:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-9&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;myfile.zip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;*
zipsplit&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;250000000&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;myfile.zip
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Would produce &lt;code&gt;myfile1.zip&lt;/code&gt;, &lt;code&gt;myfile2.zip&lt;/code&gt;, etc., all independent of each other, and none larger than 250MB (in powers of ten). &lt;code&gt;zipsplit&lt;/code&gt; will even try to organize the contents so that each resulting archive is as close as possible to the maximum size.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#find-files-that-were-modified-between-dates&#34;&gt;Find files that were modified between dates.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The best option is the &lt;code&gt;-newerXY&lt;/code&gt;. The m and t flags can be used.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;m&lt;/code&gt; The modification time of the file reference&lt;/li&gt; &lt;li&gt;&lt;code&gt;t&lt;/code&gt; reference is interpreted directly as a time&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;So the solution is&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;find&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-type&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-newermt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;20111222&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\!&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-newermt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;20111225&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The lower bound in inclusive, and upper bound is exclusive, so I added 1 day to it. And it is recursive.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add rofi launcher.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;http://www.passwordstore.org/&#34;&gt;pass&lt;/a&gt; is a command line password store&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Configure rofi launcher&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Save &lt;a href=&#34;https://raw.githubusercontent.com/carnager/rofi-pass/master/rofi-pass&#34;&gt;this script&lt;/a&gt; somewhere in your &lt;code&gt;$PATH&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Configure your window manager to launch it whenever you need a password.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#get-info-of-a-mkv-file&#34;&gt;Get info of a mkv file.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ffprobe&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;file.mkv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#clean-the-logs-of-a-unit-of-the-journal&#34;&gt;Clean the logs of a unit of the journal.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;journalctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--vacuum-time&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;1s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--unit&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you wish to clear all logs use &lt;code&gt;journalctl --vacuum-time=1s&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce Alacritty.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://alacritty.org/&#34;&gt;Alacritty&lt;/a&gt; is a modern terminal emulator that comes with sensible defaults, but allows for extensive configuration. By integrating with other applications, rather than reimplementing their functionality, it manages to provide a flexible set of features with high performance.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/alacritty/alacritty/blob/master/INSTALL.md#debianubuntu&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Clone the repo &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;clone&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://github.com/alacritty/alacritty.git
&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;alacritty
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://rustup.rs/&#34;&gt;Install &lt;code&gt;rustup&lt;/code&gt;&lt;/a&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--proto&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;=https&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--tlsv1.2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-sSf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://sh.rustup.rs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt; &lt;li&gt;To make sure you have the right Rust compiler installed, run &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;rustup&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;override&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;stable
rustup&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;stable
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt; &lt;li&gt;Install the dependencies &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;apt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cmake&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pkg-config&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libfreetype6-dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libfontconfig1-dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libxcb-xfixes0-dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libxkbcommon-dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;python3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt; &lt;li&gt;Build the release &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cargo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;build&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--release
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; If all goes well, this should place a binary at &lt;code&gt;target/release/alacritty&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Move the binary to somewhere in your PATH&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;target/release/alacritty&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;~/.local/bin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; - Check the terminfo: To make sure Alacritty works correctly, either the &lt;code&gt;alacritty&lt;/code&gt; or &lt;code&gt;alacritty-direct&lt;/code&gt; terminfo must be used. The &lt;code&gt;alacritty&lt;/code&gt; terminfo will be picked up automatically if it is installed. If the following command returns without any errors, the &lt;code&gt;alacritty&lt;/code&gt; terminfo is already installed:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;infocmp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;alacritty
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If it is not present already, you can install it globally with the following command:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tic&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-xe&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;alacritty,alacritty-direct&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;extra/alacritty.info
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://alacritty.org/config-alacritty.html&#34;&gt;Configuration&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Alacritty&#39;s configuration file uses the TOML format. It doesn&#39;t create the config file for you, but it looks for one in &lt;code&gt;~/.config/alacrity/alacritty.toml&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Not there yet&lt;/strong&gt; - &lt;a href=&#34;https://github.com/alacritty/alacritty/issues/50&#34;&gt;Support for ligatures&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt; - &lt;a href=&#34;https://alacritty.org/&#34;&gt;Homepage&lt;/a&gt; - &lt;a href=&#34;https://github.com/alacritty/alacritty&#34;&gt;Source&lt;/a&gt; - &lt;a href=&#34;https://github.com/alacritty/alacritty/blob/master/docs/features.md&#34;&gt;Docs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#set-the-vim-filetype-syntax-in-a-comment&#34;&gt;Set the vim filetype syntax in a comment.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Add somewhere in your file:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#export-environment-variables-in-a-crontab&#34;&gt;Export environment variables in a crontab.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you need to expand the &lt;code&gt;PATH&lt;/code&gt; in theory you can do it like this:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;PATH=$PATH:/usr/local/bin

* * * * * /path/to/my/script
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;I&#39;ve found however that sometimes this doesn&#39;t work and you need to specify it in the crontab line:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;* * * * * PATH=$PATH:/usr/local/bin /path/to/my/script
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Docker prune without removing the manual networks.&lt;/p&gt; &lt;p&gt;If you run the command &lt;code&gt;docker system prune&lt;/code&gt; in conjunction with &lt;a href=&#34;https://lyz-code.github.io/blue-book/watchtower/&#34;&gt;watchtower&lt;/a&gt; and manually defined networks you may run into the issue that the docker system prune acts just when the dockers are stopped and thus removing the networks, which will prevent the dockers to start. In those cases you can either make sure that docker system prune is never run when watchtower is doing the updates or you can split the command into the next script:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;date
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Pruning the containers&#34;&lt;/span&gt;
docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;container&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;prune&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--filter&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;label!=prune=false&#34;&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Pruning the images&#34;&lt;/span&gt;
docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;image&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;prune&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--filter&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;label!=prune=false&#34;&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Pruning the volumes&#34;&lt;/span&gt;
docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;volume&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;prune&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#debugging-high-iowait&#34;&gt;Debugging high IOwait.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;High I/O wait (&lt;code&gt;iowait&lt;/code&gt;) on the CPU, especially at 50%, typically indicates that your system is spending a large portion of its time waiting for I/O operations (such as disk access) to complete. This can be caused by a variety of factors, including disk bottlenecks, overloaded storage systems, or inefficient applications making disk-intensive operations.&lt;/p&gt; &lt;p&gt;Here’s a structured approach to debug and analyze high I/O wait on your server:&lt;/p&gt; &lt;p&gt;** Monitor disk I/O**&lt;/p&gt; &lt;p&gt;First, verify if disk I/O is indeed the cause. Tools like &lt;code&gt;iostat&lt;/code&gt;, &lt;code&gt;iotop&lt;/code&gt;, and &lt;code&gt;dstat&lt;/code&gt; can give you an overview of disk activity:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;&lt;code&gt;iostat&lt;/code&gt;&lt;/strong&gt;: This tool reports CPU and I/O statistics. You can install it with &lt;code&gt;apt-get install sysstat&lt;/code&gt;. Run the following command to check disk I/O stats:&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;iostat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-x&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; The &lt;code&gt;-x&lt;/code&gt; flag provides extended statistics, and &lt;code&gt;1&lt;/code&gt; means it will report every second. Look for high values in the &lt;code&gt;%util&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt; columns, which represent: - &lt;code&gt;%util&lt;/code&gt;: Percentage of time the disk is busy (ideally should be below 90% for most systems). - &lt;code&gt;await&lt;/code&gt;: Average time for I/O requests to complete.&lt;/p&gt; &lt;p&gt;If either of these values is unusually high, it indicates that the disk subsystem is likely overloaded.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;&lt;code&gt;iotop&lt;/code&gt;&lt;/strong&gt;: If you want a more granular look at which processes are consuming disk I/O, use &lt;code&gt;iotop&lt;/code&gt;:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;iotop&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This will show you the processes that are actively performing I/O operations.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;&lt;code&gt;dstat&lt;/code&gt;&lt;/strong&gt;: Another useful tool for monitoring disk I/O in real-time:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;dstat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-cdl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This shows CPU, disk, and load stats, refreshing every second. Pay attention to the &lt;code&gt;dsk/await&lt;/code&gt; value.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Check disk health&lt;/strong&gt; Disk issues such as bad sectors or failing drives can also lead to high I/O wait times. To check the health of your disks:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Use &lt;code&gt;smartctl&lt;/code&gt;&lt;/strong&gt;: This tool can give you a health check of your disks if they support S.M.A.R.T.&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;smartctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sda
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Check for any errors or warnings in the output. Particularly look for things like reallocated sectors or increasing &#34;pending sectors.&#34;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;&lt;code&gt;dmesg&lt;/code&gt; logs&lt;/strong&gt;: Look at the system logs for disk errors or warnings:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;dmesg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;error&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If there are frequent disk errors, it may be time to replace the disk or investigate hardware issues.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Look for disk saturation&lt;/strong&gt; If the disk is saturated, no matter how fast the CPU is, it will be stuck waiting for data to come back from the disk. To further investigate disk saturation:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;&lt;code&gt;df -h&lt;/code&gt;&lt;/strong&gt;: Check if your disk partitions are full or close to full.&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;df&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;&lt;code&gt;lsblk&lt;/code&gt;&lt;/strong&gt;: Check how your disks are partitioned and how much data is written to each partition:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;lsblk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;NAME,SIZE,TYPE,MOUNTPOINT
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;&lt;code&gt;blktrace&lt;/code&gt;&lt;/strong&gt;: For advanced debugging, you can use &lt;code&gt;blktrace&lt;/code&gt;, which traces block layer events on your system.&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;blktrace&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sda&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;blkparse&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This will give you very detailed insights into how the system is interacting with the block device.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Check for heavy disk-intensive processes&lt;/strong&gt; Identify processes that might be using excessive disk I/O. You can use tools like &lt;code&gt;iotop&lt;/code&gt; (as mentioned earlier) or &lt;code&gt;pidstat&lt;/code&gt; to look for processes with high disk usage:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;&lt;code&gt;pidstat&lt;/code&gt;&lt;/strong&gt;: Track per-process disk activity:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pidstat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This command will give you I/O statistics per process every second. Look for processes with high &lt;code&gt;I/O&lt;/code&gt; values (&lt;code&gt;r/s&lt;/code&gt; and &lt;code&gt;w/s&lt;/code&gt;).&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;&lt;code&gt;top&lt;/code&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;code&gt;htop&lt;/code&gt;&lt;/strong&gt;: While &lt;code&gt;top&lt;/code&gt; or &lt;code&gt;htop&lt;/code&gt; can show CPU usage, they can also show process-level disk activity. Focus on processes consuming high CPU or memory, as they might also be performing heavy I/O operations.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;check file system issues&lt;/strong&gt; Sometimes the file system itself can be the source of I/O bottlenecks. Check for any file system issues that might be causing high I/O wait.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Check file system consistency&lt;/strong&gt;: If you suspect the file system is causing issues (e.g., due to corruption), run a file system check. For &lt;code&gt;ext4&lt;/code&gt;:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;fsck&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sda1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Ensure you unmount the disk first or do this in single-user mode.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Check disk scheduling&lt;/strong&gt;: Some disk schedulers (like &lt;code&gt;cfq&lt;/code&gt; or &lt;code&gt;deadline&lt;/code&gt;) might perform poorly depending on your workload. You can check the scheduler used by your disk with:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/sys/block/sda/queue/scheduler
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can change the scheduler with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;deadline&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/sys/block/sda/queue/scheduler
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This might improve disk performance, especially for certain workloads.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Examine system logs&lt;/strong&gt; The system logs (&lt;code&gt;/var/log/syslog&lt;/code&gt; or &lt;code&gt;/var/log/messages&lt;/code&gt;) may contain additional information about hardware issues, I/O bottlenecks, or kernel-related warnings:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tail&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/log/syslog
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;or&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tail&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/log/messages
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Look for I/O or disk-related warnings or errors.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Consider hardware upgrades or tuning&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;SSD vs HDD&lt;/strong&gt;: If you&#39;re using HDDs, consider upgrading to SSDs. HDDs can be much slower in terms of I/O, especially if you have a high number of random read/write operations.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;RAID Configuration&lt;/strong&gt;: If you are using RAID, check the RAID configuration and ensure it&#39;s properly tuned for performance (e.g., using RAID-10 for a good balance of speed and redundancy).&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Memory and CPU Tuning&lt;/strong&gt;: If the server is swapping due to insufficient RAM, it can result in increased I/O wait. You might need to add more RAM or optimize the system to avoid excessive swapping.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Check for swapping issues&lt;/strong&gt; Excessive swapping can contribute to high I/O wait times. If your system is swapping (which happens when physical RAM is exhausted), I/O wait spikes as the system reads from and writes to swap space on disk.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Check swap usage&lt;/strong&gt;:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;free&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If swap usage is high, you may need to add more physical RAM or optimize applications to reduce memory pressure.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#create-a-file-with-random-data-&#34;&gt;Create a file with random data.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Of 3.5 GB&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;dd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/dev/urandom&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;of&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;random_file.bin&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;bs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;1M&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3584&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#convert-an-html-to-a-pdf&#34;&gt;Convert an html to a pdf.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Using weasyprint&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Install it with &lt;code&gt;pip install weasyprint PyMuPDF&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;weasyprint&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;input.html&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output.pdf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;It gave me better result than &lt;code&gt;wkhtmltopdf&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Using wkhtmltopdf&lt;/strong&gt; To convert the given HTML into a PDF with proper styling and formatting using a simple method on Linux, you can use &lt;code&gt;wkhtmltopdf&lt;/code&gt; with some custom options.&lt;/p&gt; &lt;p&gt;First, ensure that you have &lt;code&gt;wkhtmltopdf&lt;/code&gt; installed on your system. If not, install it using your package manager (e.g., Debian: &lt;code&gt;sudo apt-get install wkhtmltopdf&lt;/code&gt;).&lt;/p&gt; &lt;p&gt;Then, convert the HTML to PDF using &lt;code&gt;wkhtmltopdf&lt;/code&gt; with the following command:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;wkhtmltopdf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--page-size&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;A4&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--margin-top&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;15mm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--margin-bottom&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;15mm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--encoding&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;utf8&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;input.html&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output.pdf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;In this command: - &lt;code&gt;--page-size A4&lt;/code&gt;: Sets the paper size to A4. - &lt;code&gt;--margin-top 15mm&lt;/code&gt; and &lt;code&gt;--margin-bottom 15mm&lt;/code&gt;: Adds top and bottom margins of 15 mm to the PDF.&lt;/p&gt; &lt;p&gt;After running the command, you should have a nicely formatted &lt;code&gt;output.pdf&lt;/code&gt; file in your current directory. This method preserves most of the original HTML styling while providing a simple way to export it as a PDF on Linux.&lt;/p&gt; &lt;p&gt;If you need to zoom in, you can use the &lt;code&gt;--zoom 1.2&lt;/code&gt; flag. For this to work you need your css to be using the &lt;code&gt;em&lt;/code&gt; sizes.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#format-a-drive-to-use-a-fat32-system&#34;&gt;Format a drive to use a FAT32 system.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mkfs.vfat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-F&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdX
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Replace /dev/sdX with your actual drive identifier&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#get-the-newest-file-of-a-directory-with-nested-directories-and-files&#34;&gt;Get the newest file of a directory with nested directories and files.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;find&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-type&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-printf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;%T@ %p\n&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sort&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tail&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-1&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cut&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f2-&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;s2&#34;&gt;&#34; &#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#how-to-debug-a-cpu-throttling-high-alert&#34;&gt;How to debug a CPU Throttling high alert.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If the docker is using less resources than the limits but they are still small (for example 0.1 CPUs) the issue may be that the CPU spikes are being throttle before they are shown in the CPU usage, the solution is then to increase the CPU limits&lt;/p&gt; &lt;p&gt;# Create a systemd service for a non-root user&lt;/p&gt; &lt;p&gt;To set up a systemd service as a &lt;strong&gt;non-root user&lt;/strong&gt;, you can create a user-specific service file under your home directory. User services are defined in &lt;code&gt;~/.config/systemd/user/&lt;/code&gt; and can be managed without root privileges.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Check the docker images sorted by size.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;images&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--format&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;{{.Repository}}:{{.Tag}}\t{{.Size}}&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sort&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-k2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can also use the builtin &lt;code&gt;docker system df -v&lt;/code&gt; to get a better understanding of the usage of disk space.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;wezterm&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/wezterm/&#34;&gt;Wezterm&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce wezterm.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/wez/wezterm&#34;&gt;WezTerm&lt;/a&gt; is a powerful cross-platform terminal emulator and multiplexer implemented in Rust.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://wezfurlong.org/wezterm/install/linux.html&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can configure your system to use that APT repo by following these steps:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-fsSL&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://apt.fury.io/wez/gpg.key&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;gpg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--yes&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--dearmor&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/usr/share/keyrings/wezterm-fury.gpg
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;deb [signed-by=/usr/share/keyrings/wezterm-fury.gpg] https://apt.fury.io/wez/ * *&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tee&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/apt/sources.list.d/wezterm.list
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Update your dependencies:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Now you can install wezterm:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wezterm
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;or to install a nightly build:&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wezterm-nightly
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;strong&gt;Troubleshooting&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/wez/wezterm/issues/3973&#34;&gt;Install in Debian 12 error&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Install from nightly.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/wez/wezterm&#34;&gt;Code&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://wezfurlong.org/wezterm/index.html&#34;&gt;Docs&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://wezfurlong.org/wezterm/index.html&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;terminals&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/kitty/&#34;&gt;Terminals&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Suggest to use nerd fonts.&lt;/p&gt; &lt;p&gt;If you&#39;re thinking of adding a new font, you should take a look at the &lt;a href=&#34;https://www.nerdfonts.com/#home&#34;&gt;nerd fonts&lt;/a&gt; as they patch developer targeted fonts with a high number of glyphs (icons). Specifically to add a high number of extra glyphs from popular ‘iconic fonts’ such as Font Awesome, Devicons, Octicons, and others.&lt;/p&gt; &lt;p&gt;For example you can get the &lt;a href=&#34;https://github.com/ryanoasis/nerd-fonts/releases/download/v3.1.1/FiraCode.zip&#34;&gt;&lt;code&gt;FiraCode Nerd Font&lt;/code&gt;&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce Rofi.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/davatorium/rofi?tab=readme-ov-file&#34;&gt;Rofi&lt;/a&gt; is a window switcher, application launcher and dmenu replacement.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/davatorium/rofi/blob/next/INSTALL.md&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rofi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/davatorium/rofi?tab=readme-ov-file#usage&#34;&gt;Usage&lt;/a&gt;&lt;/strong&gt; To launch rofi directly in a certain mode, specify a mode with &lt;code&gt;rofi -show &amp;lt;mode&amp;gt;&lt;/code&gt;. To show the run dialog:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;rofi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-show&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;run
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Or get the options from a script:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;~/my_script.sh&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rofi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-dmenu
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Specify an ordered, comma-separated list of modes to enable. Enabled modes can be changed at runtime. Default key is Ctrl+Tab. If no modes are specified, all configured modes will be enabled. To only show the run and ssh launcher:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;rofi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-modes&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;run,ssh&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-show&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;run
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The modes to combine in combi mode. For syntax to &lt;code&gt;-combi-modes&lt;/code&gt; , see &lt;code&gt;-modes&lt;/code&gt;. To get one merge view, of window,run, and ssh:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;rofi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-show&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;combi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-combi-modes&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;window,run,ssh&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-modes&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;combi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/davatorium/rofi/blob/next/CONFIG.md&#34;&gt;Configuration&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The configuration lives at &lt;code&gt;~/.config/rofi/config.rasi&lt;/code&gt; to create this file with the default conf run:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;rofi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-dump-config&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;~/.config/rofi/config.rasi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;&#34;&gt;Use fzf to do the matching&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To run once:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;rofi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-show&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;run&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-sorting-method&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;fzf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-matching&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;fuzzy
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To persist them change those same values in the configuration.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Theme changing&lt;/strong&gt; To change the theme: - Choose the one you like most looking &lt;a href=&#34;https://davatorium.github.io/rofi/themes/themes/&#34;&gt;here&lt;/a&gt; - Run &lt;code&gt;rofi-theme-selector&lt;/code&gt; to select it - Accept it with &lt;code&gt;Alt + a&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://davatorium.github.io/rofi/current/rofi-keys.5/&#34;&gt;Keybindings change&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/davatorium/rofi/wiki/User-scripts&#34;&gt;Plugins&lt;/a&gt;&lt;/strong&gt; You can write your custom plugins. If you&#39;re on python using &lt;a href=&#34;https://github.com/bcbnz/python-rofi&#34;&gt;&lt;code&gt;python-rofi&lt;/code&gt;&lt;/a&gt; seems to be the best option although it looks unmaintained.&lt;/p&gt; &lt;p&gt;Some interesting examples are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://framagit.org/Daguhh/naivecalendar/-/tree/master?ref_type=heads&#34;&gt;Python based plugin&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://gitlab.com/vahnrr/rofi-menus/-/tree/master?ref_type=heads&#34;&gt;Creation of nice menus&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/adi1090x/rofi/tree/master&#34;&gt;Nice collection of possibilities&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/DMBuce/i3b/blob/master/bin/pickdate&#34;&gt;Date picker&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/wakatara/rofi-org-todo/blob/master/rofi-org-todo.py&#34;&gt;Orgmode capture&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Other interesting references are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://davatorium.github.io/rofi/current/rofi-keys.5/&#34;&gt;List of key bindings&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://davatorium.github.io/rofi/current/rofi-theme.5/#examples&#34;&gt;Theme guide&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt; - &lt;a href=&#34;https://github.com/davatorium/rofi?tab=readme-ov-file&#34;&gt;Source&lt;/a&gt; - &lt;a href=&#34;https://davatorium.github.io/rofi/&#34;&gt;Docs&lt;/a&gt; - &lt;a href=&#34;https://github.com/davatorium/rofi/wiki/User-scripts&#34;&gt;Plugins&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Do terminal comparison.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/alacritty/&#34;&gt;Alacritty&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Pros:&lt;/p&gt; &lt;p&gt;Cons:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The installation is difficult if you&#39;re not used to Rust.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/alacritty/alacritty/issues/50&#34;&gt;Doesn&#39;t support for ligatures&lt;/a&gt; so Fira Code with ligatures looks weird.&lt;/li&gt; &lt;li&gt;Awful docs&lt;/li&gt; &lt;li&gt;Difficult to keep updated&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/kitty/&#34;&gt;Kitty&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Pros:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Built in python&lt;/li&gt; &lt;li&gt;Supports ligatures&lt;/li&gt; &lt;li&gt;Nice docs&lt;/li&gt; &lt;li&gt;Easy installation&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Cons:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Vim bindings to move around and copy the buffer don&#39;t work well&lt;/li&gt; &lt;li&gt;When you &lt;code&gt;sudo su&lt;/code&gt; on a server you need to copy the &lt;code&gt;~/.terminfo&lt;/code&gt; otherwise the shell is broken&lt;/li&gt; &lt;li&gt;You need to replace &lt;code&gt;ssh&lt;/code&gt; so that they copy that file.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/wezterm/&#34;&gt;Wezterm&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Pros:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Nice docs&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Cons:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Dev is enough narcissistic enough to not only add it in the name of the terminal but also to say his name as the main developer.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;gotify&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gotify/&#34;&gt;Gotify&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Complete installation.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Create the data directories: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mkdir&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/data/config/gotify/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/data/gotify
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt; &lt;li&gt;Assuming you&#39;re using an external proxy create the next docker compose in &lt;code&gt;/data/config/gotify&lt;/code&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;3&#34;&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;gotify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;gotify/server&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;container_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;gotify&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;networks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;swag&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;env_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;.env&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;gotify-data:/app/data&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;networks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;swag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;external&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;swag&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;gotify-data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;driver&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;local&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;driver_opts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;none&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;bind&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;device&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/data/gotify&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;With the next &lt;code&gt;.env&lt;/code&gt; file:&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;  GOTIFY_SERVER_SSL_ENABLED=false

  GOTIFY_DATABASE_DIALECT=sqlite3
  GOTIFY_DATABASE_CONNECTION=data/gotify.db

  GOTIFY_DEFAULTUSER_NAME=admin
  GOTIFY_DEFAULTUSER_PASS=changeme

  GOTIFY_PASSSTRENGTH=10
  GOTIFY_UPLOADEDIMAGESDIR=data/images
  GOTIFY_PLUGINSDIR=data/plugins
  GOTIFY_REGISTRATION=false
  ```

* Create the service by adding a file `gotify.service` into `/etc/systemd/system/`
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; [Unit] Description=gotify Requires=docker.service After=docker.service&lt;/p&gt; &lt;p&gt;[Service] Restart=always User=root Group=docker WorkingDirectory=/data/config/gotify TimeoutStartSec=100 RestartSec=2s ExecStart=/usr/bin/docker-compose -f docker-compose.yaml up ExecStop=/usr/bin/docker-compose -f docker-compose.yaml down&lt;/p&gt; &lt;p&gt;[Install] WantedBy=multi-user.target &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;* Copy the nginx configuration in your `site-confs`

  ```

  server {
      listen 443 ssl;
      listen [::]:443 ssl;

      server_name gotify.*;

      include /config/nginx/ssl.conf;

      client_max_body_size 0;

      # enable for ldap auth (requires ldap-location.conf in the location block)
      #include /config/nginx/ldap-server.conf;

      # enable for Authelia (requires authelia-location.conf in the location block)
      #include /config/nginx/authelia-server.conf;

      location / {
          # enable the next two lines for http auth
          #auth_basic &#34;Restricted&#34;;
          #auth_basic_user_file /config/nginx/.htpasswd;

          # enable for ldap auth (requires ldap-server.conf in the server block)
          #include /config/nginx/ldap-location.conf;

          # enable for Authelia (requires authelia-server.conf in the server block)
          #include /config/nginx/authelia-location.conf;

          include /config/nginx/proxy.conf;
          include /config/nginx/resolver.conf;
          set $upstream_app gotify;
          set $upstream_port 80;
          set $upstream_proto http;
          proxy_pass $upstream_proto://$upstream_app:$upstream_port;
      }
  }
  ```
* Start the service `systemctl start gotify`
* Restart the nginx service `systemctl restart swag`
* Enable the service `systemctl enable gotify`.
* Login with the `admin` user
* Create a new user with admin permissions
* Delete the `admin` user

**Configuration**

- [Android client](https://github.com/gotify/android)
- Linux clients
  - [command line client](#command-line-client)
  - [Dunst client](https://github.com/ztpnk/gotify-dunst)
  - [gotify-desktop](https://github.com/desbma/gotify-desktop)
  - [rofi client](https://github.com/diddypod/rotify)

**Connect it with Alertmanager**

It&#39;s not trivial to connect it to Alertmanager([1](https://github.com/prometheus/alertmanager/issues/2120), [2](https://github.com/gotify/contrib/issues/21), [3](https://github.com/prometheus/alertmanager/issues/3729), [4](https://github.com/prometheus/alertmanager/issues/2120). The most popular way is to use [`alertmanager_gotify_bridge`](https://github.com/DRuggeri/alertmanager_gotify_bridge?tab=readme-ov-file).

We need to tweak the docker-compose to add the bridge:

```yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Connect it with Authentik&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Here are some guides to connect it to authentik. The problem is that the clients you want to use must support it&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/gotify/server/issues/203&#34;&gt;https://github.com/gotify/server/issues/203&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/gotify/server/issues/553&#34;&gt;https://github.com/gotify/server/issues/553&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://gotify.net/docs/&#34;&gt;Docs&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;haproxy&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/haproxy/&#34;&gt;HAProxy&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/haproxy/#automatically-ban-offending-traffic&#34;&gt;Automatically ban offending traffic.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Check these two posts:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://serverfault.com/questions/853806/blocking-ips-in-haproxy&#34;&gt;https://serverfault.com/questions/853806/blocking-ips-in-haproxy&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.loadbalancer.org/blog/simple-denial-of-service-dos-attack-mitigation-using-haproxy-2/&#34;&gt;https://www.loadbalancer.org/blog/simple-denial-of-service-dos-attack-mitigation-using-haproxy-2/&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/haproxy/#configure-haproxy-logs-to-be-sent-to-loki&#34;&gt;Configure haproxy logs to be sent to loki.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;In the &lt;code&gt;fronted&lt;/code&gt; config add the next line:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;  # For more options look at https://www.chrisk.de/blog/2023/06/haproxy-syslog-promtail-loki-grafana-logfmt/
  log-format &#39;client_ip=%ci client_port=%cp frontend_name=%f backend_name=%b server_name=%s performance_metrics=%TR/%Tw/%Tc/%Tr/%Ta status_code=%ST bytes_read=%B termination_state=%tsc haproxy_metrics=%ac/%fc/%bc/%sc/%rc srv_queue=%sq  backend_queue=%bq user_agent=%{+Q}[capture.req.hdr(0)] http_hostname=%{+Q}[capture.req.hdr(1)] http_version=%HV http_method=%HM http_request_uri=&#34;%HU&#34;&#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;At the bottom of &lt;a href=&#34;https://www.chrisk.de/blog/2023/06/haproxy-syslog-promtail-loki-grafana-logfmt/&#34;&gt;chrisk post&lt;/a&gt; is a table with all the available fields.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://programming.vip/docs/loki-configures-the-collection-of-haproxy-logs.html&#34;&gt;Programming VIP also has an interesting post&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/haproxy/#reload-haproxy&#34;&gt;Reload haproxy.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Check the config is alright &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;service&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;haproxy&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;configtest
&lt;span class=&#34;c1&#34;&gt;# Or&lt;/span&gt;
/usr/sbin/haproxy&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-V&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/haproxy/haproxy.cfg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt; &lt;li&gt;Reload the service &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;service&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;haproxy&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reload
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;If you want to do a better reload you can &lt;a href=&#34;https://serverfault.com/questions/580595/haproxy-graceful-reload-with-zero-packet-loss&#34;&gt;drop the SYN before a restart&lt;/a&gt;, so that clients will resend this SYN until it reaches the new process.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;iptables&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-I&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;INPUT&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tcp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--dport&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;80&lt;/span&gt;,443&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--syn&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-j&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;DROP
sleep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
service&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;haproxy&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reload
iptables&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-D&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;INPUT&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tcp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--dport&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;80&lt;/span&gt;,443&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--syn&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-j&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;DROP
service&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;haproxy&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reload
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;journald&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/journald/&#34;&gt;journald&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce journald.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.freedesktop.org/software/systemd/man/latest/systemd-journald.service.html&#34;&gt;journald&lt;/a&gt; is a system service that collects and stores logging data. It creates and maintains structured, indexed journals based on logging information that is received from a variety of sources:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Kernel log messages, via kmsg&lt;/li&gt; &lt;li&gt;Simple system log messages, via the &lt;code&gt;libc syslog&lt;/code&gt; call&lt;/li&gt; &lt;li&gt;Structured system log messages via the native Journal API.&lt;/li&gt; &lt;li&gt;Standard output and standard error of service units.&lt;/li&gt; &lt;li&gt;Audit records, originating from the kernel audit subsystem.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The daemon will implicitly collect numerous metadata fields for each log messages in a secure and unfakeable way.&lt;/p&gt; &lt;p&gt;Journald provides a good out-of-the-box logging experience for systemd. The trade-off is, journald is a bit of a monolith, having everything from log storage and rotation, to log transport and search. Some would argue that syslog is more UNIX-y: more lenient, easier to integrate with other tools. Which was its main criticism to begin with. When the change was made &lt;a href=&#34;https://rainer.gerhards.net/2013/05/rsyslog-vs-systemd-journal.html&#34;&gt;not everyone agreed with the migration from syslog&lt;/a&gt; or the general approach systemd took with journald. But by now, systemd is adopted by most Linux distributions, and it includes journald as well. journald happily coexists with syslog daemons, as:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Some syslog daemons can both read from and write to the journal&lt;/li&gt; &lt;li&gt;journald exposes the syslog API&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;It provides lots of features, most importantly:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Indexing. journald uses a binary storage for logs, where data is indexed. Lookups are much faster than with plain text files.&lt;/li&gt; &lt;li&gt;Structured logging. Though it’s possible with syslog, too, it’s enforced here. Combined with indexing, it means you can easily filter specific logs (e.g. with a set priority, in a set timeframe).&lt;/li&gt; &lt;li&gt;Access control. By default, storage files are split by user, with different permissions to each. As a regular user, you won’t see everything root sees, but you’ll see your own logs.&lt;/li&gt; &lt;li&gt;Automatic log rotation. You can configure journald to keep logs only up to a space limit, or based on free space.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;syncthing&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/syncthing/&#34;&gt;Syncthing&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/syncthing/#change-the-path-of-a-folder&#34;&gt;Change the path of a folder.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Shutdown Syncthing&lt;/li&gt; &lt;li&gt;Edit the config file (&lt;code&gt;~/.config/syncthing/config.xml&lt;/code&gt;)&lt;/li&gt; &lt;li&gt;Search and replace the path&lt;/li&gt; &lt;li&gt;Start again syncthing&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;wireguard&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/wireguard/&#34;&gt;Wireguard&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/wireguard/#improve-logging&#34;&gt;Improve logging.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;WireGuard doesn’t do any logging by default. If you use the WireGuard Linux kernel module (on kernel versions 5.6 or newer), you can turn on WireGuard’s dyndbg logging, which sends log messages to the kernel message buffer, kmsg. You can then use the standard dmesg utility to read these messages. Also, many Linux systems have a logging daemon like rsyslogd or journald that automatically captures and stores these messages.&lt;/p&gt; &lt;p&gt;First, enable WireGuard &lt;code&gt;dyndbg&lt;/code&gt; logging with the following commands:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;modprobe&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wireguard
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;module&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wireguard&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;+p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/sys/kernel/debug/dynamic_debug/control
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Once you do that, you’ll be able to see WireGuard log messages in the kernel message facility, if your system is set up with &lt;code&gt;rsyslogd&lt;/code&gt;, &lt;code&gt;journald&lt;/code&gt;, or a similar logging daemon. With &lt;code&gt;rsyslogd&lt;/code&gt;, check the &lt;code&gt;/var/log/kern.log&lt;/code&gt; or &lt;code&gt;/var/log/messages&lt;/code&gt; file. With &lt;code&gt;journald&lt;/code&gt;, run &lt;code&gt;journalctl -ek&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/wireguard/#monitor-wireguard&#34;&gt;Monitor wireguard.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.procustodibus.com/blog/2021/01/how-to-monitor-wireguard-activity/&#34;&gt;https://www.procustodibus.com/blog/2021/01/how-to-monitor-wireguard-activity/&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://techoverflow.net/2021/12/31/how-to-check-if-wireguard-client-peer-is-connected/&#34;&gt;https://techoverflow.net/2021/12/31/how-to-check-if-wireguard-client-peer-is-connected/&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/wireguard/#check-the-status-of-the-tunnel&#34;&gt;Check the status of the tunnel.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;One method is to do ping between VPN IP addresses or run command &lt;code&gt;wg show`` from the server or from the client. Below you can see&lt;/code&gt;wg show`` command output where VPN is &lt;em&gt;not&lt;/em&gt; up.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;show
interface:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wg0
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;public&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;key:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;qZ7+xNeXCjKdRNM33Diohj2Y/KSOXwvFfgTS1LRx+EE&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;private&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;key:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;hidden&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;listening&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;port:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;45703&lt;/span&gt;

peer:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mhLzGkqD1JujPjEfZ6gkbusf3sfFzy+1KXBwVNBRBHs&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;endpoint:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3&lt;/span&gt;.133.147.235:51820
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;allowed&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ips:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;.100.100.1/32
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;transfer:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;B&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;received,&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;592&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;B&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sent
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;persistent&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;keepalive:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;every&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;seconds
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The below output from the &lt;code&gt;wg show&lt;/code&gt; command indicates the VPN link is up. See the line with &lt;code&gt;last handshake time&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;show
interface:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wg0
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;public&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;key:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;qZ7+xNeXCjKdRNM33Diohj2Y/KSOXwvFfgTS1LRx+EE&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;private&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;key:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;hidden&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;listening&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;port:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;49785&lt;/span&gt;

peer:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;6lf4SymMbY+WboI4jEsM+P9DhogzebSULrkFowDTt0M&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;endpoint:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3&lt;/span&gt;.133.147.235:51820
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;allowed&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ips:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;.100.100.1/32
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;latest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;handshake:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;seconds&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ago
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;transfer:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;732&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;B&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;received,&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;820&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;B&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sent
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;persistent&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;keepalive:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;every&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;seconds
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;android&#34;&gt;Android&lt;/h3&gt; &lt;h4 id=&#34;grapheneos&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/grapheneos/&#34;&gt;GrapheneOS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/grapheneos/#disable-bluetooth-and-wifi-once-it&#39;s-disconnected&#34;&gt;Disable Bluetooth and Wifi once it&#39;s disconnected.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you don&#39;t want to go spreading your SSIDs you can configure graphene to disable wifi and bluetooth X minutes after loosing connection.&lt;/p&gt; &lt;p&gt;For Wifi:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Go to Settings &amp;gt; network &amp;amp; internet &amp;gt; internet &amp;gt; network preferences&lt;/li&gt; &lt;li&gt;Select Turn off Wi-Fi automatically, for example after 2 minutes&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;For Bluetooth:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Go to Settings &amp;gt; connected devices &amp;gt; connection preferences&amp;gt; bluetooth&lt;/li&gt; &lt;li&gt;Select Turn Bluetooth off automatically, for example after 2 minutes&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;gadgetbridge&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gadgetbridge/&#34;&gt;GadgetBridge&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gadgetbridge/#installation&#34;&gt;Installation on GrapheneOS.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;On &lt;a href=&#34;https://lyz-code.github.io/blue-book/grapheneos/&#34;&gt;GrapheneOS&lt;/a&gt; you may need to &lt;a href=&#34;https://support.google.com/android/answer/12623953?hl=en&#34;&gt;enable the restricted permissions&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;android-sdk-platform-tools&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/android_sdk/&#34;&gt;Android SDK Platform tools&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce android_sdk.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://developer.android.com/tools/releases/platform-tools&#34;&gt;Android SDK Platform tools&lt;/a&gt; is a component for the Android SDK. It includes tools that interface with the Android platform, primarily adb and fastboot.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://developer.android.com/tools/releases/platform-tools&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;While many Linux distributions already package Android Platform Tools (for example &lt;code&gt;android-platform-tools-base&lt;/code&gt; on Debian), it is preferable to install the most recent version from the official website. Packaged versions might be outdated and incompatible with most recent Android handsets.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Download &lt;a href=&#34;https://dl.google.com/android/repository/platform-tools-latest-linux.zip&#34;&gt;the latest toolset&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Extract it somewhere in your filesystem&lt;/li&gt; &lt;li&gt;Create links to the programs you want to use in your &lt;code&gt;$PATH&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Next you will need to enable debugging on the Android device you are testing. &lt;a href=&#34;https://developer.android.com/studio/command-line/adb&#34;&gt;Please follow the official instructions on how to do so.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Connecting over USB&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To use &lt;code&gt;adb&lt;/code&gt; with a device connected over USB, you must enable USB debugging in the device system settings, under Developer options. On Android 4.2 (API level 17) and higher, the Developer options screen is hidden by default.&lt;/p&gt; &lt;p&gt;&lt;em&gt;Enable the Developer options&lt;/em&gt;&lt;/p&gt; &lt;p&gt;To make it visible, &lt;a href=&#34;https://developer.android.com/studio/debug/dev-options#enable&#34;&gt;enable Developer options&lt;/a&gt;. On Android 4.1 and lower, the Developer options screen is available by default. On Android 4.2 and higher, you must enable this screen.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;On your device, find the Build number option (Settings &amp;gt; About phone &amp;gt; Build number)&lt;/li&gt; &lt;li&gt;Tap the Build Number option seven times until you see the message You are now a developer! This enables developer options on your device.&lt;/li&gt; &lt;li&gt;Return to the previous screen to find Developer options at the bottom.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;em&gt;Enable USB debugging&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Before you can use the debugger and other tools, you need to enable USB debugging, which allows Android Studio and other SDK tools to recognize your device when connected via USB.&lt;/p&gt; &lt;p&gt;Enable USB debugging in the device system settings under Developer options. You can find this option in one of the following locations, depending on your Android version:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Android 9 (API level 28) and higher: Settings &amp;gt; System &amp;gt; Advanced &amp;gt; Developer Options &amp;gt; USB debugging&lt;/li&gt; &lt;li&gt;Android 8.0.0 (API level 26) and Android 8.1.0 (API level 27): Settings &amp;gt; System &amp;gt; Developer Options &amp;gt; USB debugging&lt;/li&gt; &lt;li&gt;Android 7.1 (API level 25) and lower: Settings &amp;gt; Developer Options &amp;gt; USB debugging&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;em&gt;Test it works&lt;/em&gt;&lt;/p&gt; &lt;p&gt;If everything is configured appropriately you should see your device when launching the command &lt;code&gt;adb devices&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;&lt;em&gt;Create udev rules if it fails&lt;/em&gt;&lt;/p&gt; &lt;p&gt;If you see the next error:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;failed to open device: Access denied (insufficient permissions)

* failed to start daemon
adb: failed to check server version: cannot connect to daemon
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;It indicates an issue with permissions when &lt;code&gt;adb&lt;/code&gt; tries to communicate with the device via USB. Here are some steps you can take to resolve this issue:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Check USB permissions&lt;/li&gt; &lt;li&gt;Ensure that you have the necessary permissions to access the USB device. If you&#39;re running on Linux, check if the device has appropriate udev rules.&lt;/li&gt; &lt;li&gt; &lt;p&gt;You can try adding your user to the &lt;code&gt;plugdev&lt;/code&gt; group:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;usermod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-aG&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;plugdev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$USER&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Make sure you have a &lt;code&gt;udev&lt;/code&gt; rule for Android devices in &lt;code&gt;/etc/udev/rules.d/&lt;/code&gt;. If not, you can create one by adding a file like &lt;code&gt;51-android.rules&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;touch&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/udev/rules.d/51-android.rules
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Add this line to the file to grant access to Android devices:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;SUBSYSTEM&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;usb&#34;&lt;/span&gt;,&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ATTR&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;idVendor&lt;span class=&#34;o&#34;&gt;}==&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;18d1&#34;&lt;/span&gt;,&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;MODE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;0666&#34;&lt;/span&gt;,&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;GROUP&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;plugdev&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Reload the &lt;code&gt;udev&lt;/code&gt; rules:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;udevadm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;control&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--reload-rules
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;service&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;udev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;restart
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Unplug and reconnect the USB device. &lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://developer.android.com/tools/releases/platform-tools&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;icsx5&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/icsx5/&#34;&gt;ICSx5&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce ICSx5.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://f-droid.org/packages/at.bitfire.icsdroid/&#34;&gt;ICSx5&lt;/a&gt; is an android app to sync calendars.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/bitfireAT/icsx5&#34;&gt;Source&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://f-droid.org/packages/at.bitfire.icsdroid/&#34;&gt;F-droid&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;signal&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/signal/&#34;&gt;Signal&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/signal/#use-the-molly-foss-android-client&#34;&gt;Use the Molly FOSS android client.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Molly is an independent Signal fork for Android. The advantages are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Contains no proprietary blobs, unlike Signal.&lt;/li&gt; &lt;li&gt;Protects database with passphrase encryption.&lt;/li&gt; &lt;li&gt;Locks down the app automatically when you are gone for a set period of time.&lt;/li&gt; &lt;li&gt;Securely shreds sensitive data from RAM.&lt;/li&gt; &lt;li&gt;Automatic backups on a daily or weekly basis.&lt;/li&gt; &lt;li&gt;Supports SOCKS proxy and Tor via Orbot.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/mollyim/mollyim-android/wiki/Migrating-From-Signal&#34;&gt;Migrate from Signal&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Note, the migration should be done when the available Molly version is equal to or later than the currently installed Signal app version.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Verify your Signal backup passphrase. In the Signal app: Settings &amp;gt; Chats &amp;gt; Chat backups &amp;gt; Verify backup passphrase.&lt;/li&gt; &lt;li&gt;Optionally, put your phone offline (enable airplane mode or disable data services) until after Signal is uninstalled in step 5. This will prevent the possibility of losing any Signal messages that are received during or after the backup is created.&lt;/li&gt; &lt;li&gt;Create a Signal backup. In the Signal app, go to Settings &amp;gt; Chats &amp;gt; Chat backups &amp;gt; Create backup.&lt;/li&gt; &lt;li&gt;Uninstall the Signal app. Now you can put your phone back online (disable airplane mode or re-enable data services).&lt;/li&gt; &lt;li&gt;Install the Molly or Molly-FOSS app.&lt;/li&gt; &lt;li&gt;Open the Molly app. Enable database encryption if desired. As soon as the option is given, tap Transfer or restore account. Answer any permissions questions.&lt;/li&gt; &lt;li&gt;Choose to Restore from backup and tap Choose backup. Navigate to your Signal backup location (Signal/Backups/, by default) and choose the backup that was created in step 3.&lt;/li&gt; &lt;li&gt;Check the backup details and then tap Restore backup to confirm. Enter the backup passphrase when requested.&lt;/li&gt; &lt;li&gt;If asked, choose a new folder for backup storage. Or choose Not Now and do it later.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Consider also:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Any previously linked devices will need to be re-linked. Go to Settings &amp;gt; Linked devices in the Molly app. If Signal Desktop is not detecting that it is no longer linked, try restarting it.&lt;/li&gt; &lt;li&gt;Verify your Molly backup settings and passphrase at Settings &amp;gt; Chats &amp;gt; Chat backups (to change the backup folder, disable and then enable backups). Tap Create backup to create your first Molly backup.&lt;/li&gt; &lt;li&gt;When you are satisfied that Molly is working, you may want to delete the old Signal backups (in Signal/Backups, by default).&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;arts&#34;&gt;Arts&lt;/h2&gt; &lt;h3 id=&#34;cooking&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/cooking/&#34;&gt;Cooking&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/cooking/#comer-naranja-por-la-noche&#34;&gt;Comer naranja por la noche.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&#34;Por la mañana oro, al mediodía plata y por la noche mata&#34;. Así de tajante se muestra el refranero español con respecto a la naranja y el melón. La naranja es una fruta ácida y por esta razón es recomendable evitar su consumo por la noche. Y es que este alto nivel de acidez puede provocar una digestión lenta y sensación de acidez y ardor en el estómago. Directamente relacionado con estos síntomas puede sobrevenir dolor de estómago y esto conducirnos a un descanso poco placentero durante la noche. Así, lo mejor es evitar su consumo a última hora del día. Si encima le añades unos trocitos de chocolate negro dificultarás el tránsito intestinal (por las grasas) y harás que te cueste más conciliar el sueño ya que es estimulante. Pero qué rico sabe de postre de cena xD.&lt;/p&gt; &lt;p&gt;Estas consecuencias varían en función de las personas y de su sistema digestivo. Así, este alimento sí puede resultar saludable para ciertas personas sin problemas gástricos y un alto nivel de tolerancia a este alimento.&lt;/p&gt; &lt;p&gt;Lo más aconsejable es consumirla por la mañana. Tomar una naranja a primera hora del día te aportará una buena dosis de vitamina C y fibra.&lt;/p&gt; &lt;p&gt;Siempre es recomendable tomar la fruta directamente y evitar los zumos, aunque sean naturales. De esta forma nos sentiremos más saciados y añadiremos más fibra y menos azúcares a nuestra dieta.&lt;/p&gt; &lt;p&gt;Además, la acidez de las naranjas que podría perjudicarnos por la noche es perfectamente tolerable por la mañana incluso si la tomamos en ayunas. De esta forma, podremos ir asimilando sus propiedades durante todo el día.&lt;/p&gt; &lt;p&gt;Estas frutas tienen un gran efecto antioxidante. Además, su gran contenido en vitamina C es un refuerzo inigualable para el sistema inmunológico y ayuda a combatir la anemia. También es un remedio ideal para tratar los resfriados y las gripes.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/cooking/#por-qué-no-vale-con-quitar-la-parte-del-moho-de-los-alimentos&#34;&gt;Por qué no vale con quitar la parte del moho de los alimentos.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.eldiario.es/consumoclaro/micotoxinas-alimentos-no-basta-quitar-parte-enmohecida_1_11275873.html&#34;&gt;Artículo&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;cleaning&#34;&gt;Cleaning&lt;/h3&gt; &lt;h4 id=&#34;cleaning-tips&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/cleaning_tips/&#34;&gt;Cleaning tips&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Cleaning car headlights.&lt;/p&gt; &lt;p&gt;If you need to clean the car headlights you can use a mixture of one squeezed lemon and two spoonfuls of baking soda&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;parkour&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/parkour/&#34;&gt;Parkour&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/parkour/#warming-up&#34;&gt;Warming up.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Never do static stretches if you&#39;re cold, it&#39;s better to do dynamic stretches.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Take the joints through rotations&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Head:&lt;/li&gt; &lt;li&gt;Nod 10 times&lt;/li&gt; &lt;li&gt;Say no 10 times&lt;/li&gt; &lt;li&gt;Ear shoulder 10 times&lt;/li&gt; &lt;li&gt; &lt;p&gt;Circles 10 times each direction&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Shoulders&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Circles back 10 times&lt;/li&gt; &lt;li&gt; &lt;p&gt;Circles forward 10 times&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Elbows&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Circles 10 each direction&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Wrists:&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Circle 10 each direction&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Chest:&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Chest out/in 10 times&lt;/li&gt; &lt;li&gt;Chest one side to the other 10 times&lt;/li&gt; &lt;li&gt; &lt;p&gt;Chest in circles&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Hips:&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Circles 10 each direction&lt;/li&gt; &lt;li&gt; &lt;p&gt;Figure eight 10 times each direction&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Knees:&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Circular rotations 10 each direction feet and knees together&lt;/li&gt; &lt;li&gt;10 ups and downs with knees together&lt;/li&gt; &lt;li&gt; &lt;p&gt;Circular rotations 10 each direction feet waist width&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Ankles:&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Circular 10 rotations each direction&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Light exercises&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;10 steps forward of walking on your toes, 10 back&lt;/li&gt; &lt;li&gt;10 steps forward of walking on your toes feet rotated outwards, 10 back&lt;/li&gt; &lt;li&gt;10 steps forward of walking on your toes feet rotated inwards, 10 back&lt;/li&gt; &lt;li&gt;10 steps forward of walking on your heels feet rotated outwards, 10 back&lt;/li&gt; &lt;li&gt; &lt;p&gt;10 steps forward of walking on your heels feet rotated inwards, 10 back&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;2 x 10 x Side step, carry the leg up (from out to in) while you turn 180, keep on moving on that direction&lt;/p&gt; &lt;/li&gt; &lt;li&gt;2 x 10 x Front step carrying the leg up (from in to out)while you turn 45, then side step, keep on moving on that direction&lt;/li&gt; &lt;li&gt;10 light skips on one leg: while walking forward lift your knee and arms and do a slight jump&lt;/li&gt; &lt;li&gt;10 steps with high knees&lt;/li&gt; &lt;li&gt;10 steps with heel to butt&lt;/li&gt; &lt;li&gt; &lt;p&gt;10 side shuffles (like basketball defense)&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;5 lunges forward, 5 backwards&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;10 rollups and downs from standing position&lt;/p&gt; &lt;/li&gt; &lt;li&gt;5 push-ups&lt;/li&gt; &lt;li&gt;10 rotations from the pushup position on each direction with straigth arms&lt;/li&gt; &lt;li&gt;5 push-ups&lt;/li&gt; &lt;li&gt;10 rotations from the pushup position on each direction with shoulders at ankle level&lt;/li&gt; &lt;li&gt; &lt;p&gt;3 downward monkeys: from piramid do a low pushup and go to cobra, then a pushup&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;10 steps forward walking on all fours&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Strengthen your knees&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Follow &lt;a href=&#34;#strengthen-your-knees&#34;&gt;there steps&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Transit to the parkour place&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Go by bike, skate, jogging to the parkour place&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;music&#34;&gt;Music&lt;/h3&gt; &lt;h4 id=&#34;sister-rosetta-tharpe&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/sister_rosetta_tharpe/&#34;&gt;Sister Rosetta Tharpe&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Sister Rosetta Tharpe.&lt;/p&gt; &lt;p&gt;Sister Rosetta Tharpe was a visionary, born in 1915 she started shredding the guitar in ways that did not exist in that time. Yes, she founded Rock and Roll. It&#39;s lovely to see a gospel singer with an electrical guitar.&lt;/p&gt; &lt;p&gt;In &lt;a href=&#34;https://yewtu.be/watch?v=JeaBNAXfHfQ&#34;&gt;this video&lt;/a&gt; you&#39;ll be able to understand how awesome she ws.&lt;/p&gt; &lt;p&gt;Videos:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://yewtu.be/watch?v=JeaBNAXfHfQ&#34;&gt;Up Above my head&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://yewtu.be/watch?v=Y9a49oFalZE&#34;&gt;Didn&#39;t it rain? 1964&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://yewtu.be/watch?v=UnDMangsOMc&#34;&gt;Nice Best of compilation&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;drawing&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/drawing/drawing/&#34;&gt;Drawing&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/drawing/drawing/#books&#34;&gt;Drawing book recommendation.&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;languages_1&#34;&gt;Languages&lt;/h2&gt; &lt;h3 id=&#34;castellano&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/castellano/&#34;&gt;Castellano&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/castellano/#el-agua-o-la-agua?&#34;&gt;El agua o la agua?.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;El sustantivo agua es de género femenino, pero tiene la particularidad de comenzar por /a/ tónica (la vocal tónica de una palabra es aquella en la que recae el acento de intensidad: [água]). Por razones de fonética histórica, este tipo de palabras seleccionan en singular la forma &lt;code&gt;el&lt;/code&gt; del artículo, en lugar de la forma femenina normal &lt;code&gt;la&lt;/code&gt;. Esta regla solo opera cuando el artículo antecede inmediatamente al sustantivo, de ahí que digamos el agua, el área, el hacha; pero, si entre el artículo y el sustantivo se interpone otra palabra, la regla queda sin efecto, de ahí que digamos la misma agua, la extensa área, la afilada hacha. Puesto que estas palabras son femeninas, los adjetivos deben concordar siempre en femenino: el agua clara, el área extensa, el hacha afilada (y no el agua claro, el área extenso, el hacha afilado).&lt;/p&gt; &lt;p&gt;Por su parte, el indefinido &lt;code&gt;una&lt;/code&gt; toma generalmente la forma &lt;code&gt;un&lt;/code&gt; cuando antecede inmediatamente a sustantivos femeninos que comienzan por /a/ tónica: un área, un hacha, un águila (si bien no es incorrecto, aunque sí poco frecuente, utilizar la forma plena una: una área, una hacha, una águila). Asimismo, los indefinidos &lt;code&gt;alguna&lt;/code&gt; y &lt;code&gt;ninguna&lt;/code&gt; pueden adoptar en estos casos las formas apocopadas (algún alma, ningún alma) o mantener las formas plenas (alguna alma, ninguna alma).&lt;/p&gt; &lt;p&gt;Al tratarse de sustantivos femeninos, con los demostrativos este, ese, aquel o con cualquier otro adjetivo determinativo, como todo, mucho, poco, otro, etc., deben usarse las formas femeninas correspondientes: esta hacha, aquella misma arma, toda el agua, mucha hambre, etc. (y no este hacha, aquel mismo arma, todo el agua, mucho hambre, etc.)&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;galego&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/galego/&#34;&gt;Galego&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;New: Add some galego vocabulary.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce galego.&lt;/p&gt; &lt;p&gt;O &lt;a href=&#34;https://gl.wikipedia.org/wiki/Lingua_galega&#34;&gt;galego&lt;/a&gt; é unha lingua indoeuropea que pertence á póla de linguas románicas. É a lingua propia de Galiza, onde é falada por uns 2.4 millóns de galegas. Á parte de en Galiza, a lingua falase tamén en territórios limítrofes con esta comunidade, ainda que sen estatuto de oficialidade, asi como pola diáspora galega que emigrou a outras partes do estado español, América latina, os Estados Unidos, Suíza e outros países do Europa.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/galego/#te-e-che.-trucos-para-saber-diferencialos&#34;&gt;Te e che. Trucos para saber diferencialos.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;En galego temos dúas formas para o pronome átono da segunda persoa do singular: te e che.&lt;/p&gt; &lt;p&gt;O pronome te ten a función de complemento directo (CD) e o pronome che de complemento indirecto (CI).&lt;/p&gt; &lt;p&gt;Cando se utiliza o pronome te?&lt;/p&gt; &lt;p&gt;O pronome te utilízase cando ten a función de CD, propio dos verbos transitivos, xa que alude ao ser ou ao obxecto sobre o que recae a acción verbal.&lt;/p&gt; &lt;p&gt;Se convertemos a oración en pasiva, o CD pasa a ser o suxeito. Por exemplo:&lt;/p&gt; &lt;p&gt;Vinte na cafetería / Ti fuches visto por min na cafetería.&lt;/p&gt; &lt;p&gt;Cando se utiliza o pronome che?&lt;/p&gt; &lt;p&gt;O pronome che utilízase cando ten a función de CI, xa que indica o destinatario da acción expresada polo verbo. Por exemplo:&lt;/p&gt; &lt;p&gt;Díxenche a verdade.&lt;/p&gt; &lt;p&gt;Compreiche unhas lambonadas.&lt;/p&gt; &lt;p&gt;Truco para saber diferencialos&lt;/p&gt; &lt;p&gt;Un truco moi rápido para diferenciarmos os pronomes te e che é substituír eses pronomes de segunda persoa polos de terceira.&lt;/p&gt; &lt;p&gt;Se podemos cambiar ese pronome por o/lo/no ou a/la/na, quere dicir que o pronome vai ser de CD. Polo tanto, temos que poñer te.&lt;/p&gt; &lt;p&gt;Saudeite onte pola rúa / Saudeino onte pola rúa.&lt;/p&gt; &lt;p&gt;Chameite por teléfono / Chameina por teléfono.&lt;/p&gt; &lt;p&gt;Se podemos substituílo por un lle, significa que é un pronome de CI e que debemos utilizar o che.&lt;/p&gt; &lt;p&gt;Lévoche mañá os apuntamentos / Lévolle mañá os apuntamentos.&lt;/p&gt; &lt;p&gt;Collinche as entradas do concerto / Collinlle as entradas do concerto.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/galego/#uso-de-asemade&#34;&gt;Uso de asemade.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Asemade pode utilizarse como adverbio cando ten o significado de ‘ao mesmo tempo’ ou ‘simultaneamente’. Ainda que normalmente úsase no registro culto, non utilizalo na fala.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Non se pode comer e falar asemade.&lt;/li&gt; &lt;li&gt;Non podes facer os deberes e ver a televisión asemade, pois non te concentras.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Tamén se pode utilizar como conxunción co significado de ‘tan pronto como’.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Foi o primeiro que vimos asemade entramos.&lt;/li&gt; &lt;li&gt;Recoñecino asemade o vin.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;É incorrecto empregar asemade como sinónimo de tamén, ademais ou igualmente.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/galego/#referencias&#34;&gt;Referencias e libros de gramática.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Referencias:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://academia.gal/dicionario&#34;&gt;Dicionario&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://tradutor.dacoruna.gal/fron-trad/index_es.html&#34;&gt;Traductor&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://pensatermos.amesa.gal&#34;&gt;Juego Pensatermos&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;http://cotovia.org/proxecto/conxugador/index.html&#34;&gt;Conxugador de verbos&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.lingua.gal/o-galego/aprendelo/celga-1/materiais-de-clase&#34;&gt;Celga-1 materiais&lt;/a&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;a href=&#34;https://www.lingua.gal/recursos/para-aprender-o-galego&#34;&gt;Recursos para aprender o galego&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;a href=&#34;https://orgullogalego.gal/musica-en-galego/&#34;&gt;Recompilación de grupos de música en galego&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?app=desktop&amp;amp;v=7al60UuHlU8&amp;amp;feature=youtu.be&#34;&gt;Conversas do fenómeno das persoas neofalantes e o futuro do idioma&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Libros gramática:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.xerais.gal/libro.php?id=927711&#34;&gt;Gramática da Lingua Galega de Xosé Feixó Cid&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.xerais.gal/libro.php?id=3337926&#34;&gt;Como falar e escribir en galego con corrección e fluidez de Carlos Callón&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://editorialgalaxia.gal/produto/manual-de-conxugacion-verbal-da-lingua-galega/&#34;&gt;Manual de conxugación verbal da lingua galega de Avelino Hermida&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://editorialgalaxia.gal/produto/dicionario-galaxia-de-usos-e-dificultades-da-lingua-galega/&#34;&gt;Dicionario Galaxia de usos e dificultades da lingua galega de Benigno Fernández Salgado&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;science&#34;&gt;Science&lt;/h2&gt; &lt;h3 id=&#34;artificial-intelligence&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/ai/&#34;&gt;Artificial Intelligence&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ai/#tools&#34;&gt;Add aider tool.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://aider.chat/&#34;&gt;Aider&lt;/a&gt; lets you pair program with LLMs, to edit code in your local git repository. Start a new project or work with an existing git repo. Aider works best with GPT-4o &amp;amp; Claude 3.5 Sonnet and can connect to almost any LLM.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;whisper&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/whisper/&#34;&gt;Whisper&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce whisper.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://pypi.org/project/openai-whisper/&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Web interfaces&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/pluja/whishper?tab=readme-ov-file&#34;&gt;Whishper&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/jhj0517/Whisper-WebUI?tab=readme-ov-file&#34;&gt;Whisper-WebUI&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Command line tools&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/SYSTRAN/faster-whisper?tab=readme-ov-file&#34;&gt;faster-whisper&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/Softcatala/whisper-ctranslate2&#34;&gt;whisper-ctranslate2&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/m-bain/whisperX&#34;&gt;whisperX&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/MahmoudAshraf97/whisper-diarization&#34;&gt;whisper-diarization&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/geekodour/wscribe&#34;&gt;wscribe&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://pypi.org/project/openai-whisper/&#34;&gt;Pypi&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;coding-by-voice&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding_by_voice/&#34;&gt;Coding by Voice&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Coding by voice.&lt;/p&gt; &lt;p&gt;Coding by voice command requires two kinds of software: a &lt;a href=&#34;https://lyz-code.github.io/blue-book/speech_recognition/&#34;&gt;speech-recognition engine&lt;/a&gt; and a platform for voice coding. Dragon from Nuance, a speech-recognition software developer in Burlington, Massachusetts, is an advanced engine and is widely used for programming by voice. On the platform side, VoiceCode by Ben Meyer and Talon by Ryan Hileman (both are for Mac OS only) are popular.&lt;/p&gt; &lt;p&gt;Coding by voice platforms:&lt;/p&gt; &lt;p&gt;Two platforms for voice programming are Caster and Aenea, the latter of which runs on Linux. Both are free and open source, and enable voice-programming functionality in Dragonfly, which is an open-source Python framework that links actions with voice commands detected by a speech-recognition engine. Saphra tried Dragonfly, but found that setup required more use of her hands than she could tolerate.&lt;/p&gt; &lt;p&gt;All of these platforms for voice command work independently of coding language and text editor, and so can also be used for tasks outside programming. Pimentel, for instance, uses voice recognition to write e-mails, which he finds easier, faster and more natural than typing.&lt;/p&gt; &lt;p&gt;To the untrained ear, coding by voice command sounds like staccato bursts of a secret language. &lt;a href=&#34;https://www.youtube.com/watch?v=8SkdfdXWYaI&#34;&gt;Rudd’s video&lt;/a&gt; is full of terms like ‘slap’ (hit return), ‘sup’ (search up) and ‘mara’ (mark paragraph).&lt;/p&gt; &lt;p&gt;Unlike virtual personal assistants such as Apple’s Siri or Google’s Alexa, VoiceCode and Talon don’t do natural-language processing, so spoken instructions have to precisely match the commands that the system already knows. But both platforms use continuous command recognition, so users needn’t pause between commands, as Siri and Alexa require.&lt;/p&gt; &lt;p&gt;VoiceCode commands typically use words not in the English language, because if you use an English word as a command, such as ‘return’, it means you can never type out that word. By contrast, Talon, Aenea and Caster feature dynamic grammar, a tool that constantly updates which words the software can recognize on the basis of which applications are open. This means users can give English words as commands without causing confusion.&lt;/p&gt; &lt;p&gt;In addition to voice recognition, Talon can also replace a computer mouse with eye tracking, which requires a Tobii 4c eye tracker (US$150). Other eye-mousing systems generally require both the eye tracker and head-tracking hardware, such as the TrackIR from NaturalPoint. “I want to make fully hands-free use of every part of a desktop computer a thing,” says Hileman. Other mouse replacements also exist; Pimentel uses one called SmartNav.&lt;/p&gt; &lt;p&gt;Voice command requires at least a decent headset or microphone. Many users choose a unidirectional microphone so that others can talk to them while they are dictating code. One such mic, a cardioid mic, requires special equipment to supply power, and hardware costs can reach $400, says Pimentel.&lt;/p&gt; &lt;p&gt;The software can cost several hundred dollars too. The speech-recognition engine Dragon Professional costs $300, as does VoiceCode. Caster and Aenea are free and open source. Talon is available for free, but requires a separate speech-recognition engine. A beta version of Talon that includes a built-in speech-recognition engine is currently available to Hileman’s Patreon supporters for $15 per month. &lt;/p&gt; &lt;p&gt;Whether or not users have RSI, it can be difficult and frustrating to start programming by voice. It took a month and a half for Pimentel to get up to speed, he says, and there were days when he was ready to throw in the towel. He printed out 40 pages of commands and forced himself to look at them until he learnt them. Saphra needed two months of coding, a little every day, before she felt that it was a “perfectly enjoyable experience and I could see myself doing this for a living”.&lt;/p&gt; &lt;p&gt;After the initial learning curve, users often create custom prompts for commonly used commands as the need arises. &lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;data-analysis&#34;&gt;Data Analysis&lt;/h3&gt; &lt;h4 id=&#34;parsers&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/parsers/&#34;&gt;Parsers&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/parsers/#learning-about-parsers&#34;&gt;Learning about parsers.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Parsers are a whole world. I kind of feel a bit lost right now and I&#39;m searching for good books on the topic. So far I&#39;ve found:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://craftinginterpreters.com/introduction.html&#34;&gt;Crafting Interpreters&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Pros: - Pleasant to read - Doesn&#39;t use external tools, you implement it from scratch. - Multiple format: EPUB, PDF, web - You can read it for free - Cute drawings &amp;lt;3&lt;/p&gt; &lt;p&gt;Cons: - Code snippets are on Java and C - Doesn&#39;t use external tools, you implement it from scratch - It&#39;s long&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Compilers: Principles, Techniques, and Tools by Aho, Alfred V. &amp;amp; Monica S. Lam &amp;amp; Ravi Sethi &amp;amp; Jeffrey D. Ullman&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Pros: - EPUB&lt;/p&gt; &lt;p&gt;Cons: - Code snippets are on C++&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Parsing Techniques: A Practical Guide by Dick Grune and Ceriel J.H Jacobs&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Pros: - Gives an overview of many grammars and parsers&lt;/p&gt; &lt;p&gt;Cons: - Only in PDF - It&#39;s long - Too focused on the theory, despite the name xD&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;other&#34;&gt;Other&lt;/h2&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Inhibit rules between times.&lt;/p&gt; &lt;p&gt;To prevent some alerts to be sent between some hours you can use the &lt;code&gt;time_intervals&lt;/code&gt; alertmanager configuration.&lt;/p&gt; &lt;p&gt;This can be useful for example if your backup system triggers some alerts that you don&#39;t need to act on.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;route&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;receiver&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;email&#39;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;group_by&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;job&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;alertname&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;group_wait&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;5m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;group_interval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;5m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;repeat_interval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;12h&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;routes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;receiver&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;email&#39;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;matchers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;alertname =~ &#34;HostCpuHighIowait|HostContextSwitching|HostUnusualDiskWriteRate&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;hostname = backup_server&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;mute_time_intervals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;night&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;time_intervals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;night&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;time_intervals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;start_time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;02:00&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;end_time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;07:00&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Thoughts on the reviews themselves.&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Keep It Simple: It&#39;s important for the process to be light enough that you want to actually do it, so you see it as a help instead of a burden. It&#39;s always better to do a small and quick review rather than nothing at all. At the start of the review analyze yourself to assess how much energy do you have and decide which steps of the review you want to do.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Review approaches: In the past I used the &lt;a href=&#34;https://lyz-code.github.io/blue-book/life_logging/&#34;&gt;life logging&lt;/a&gt; tools to analyze the past in order to understand what I achieved and take it as a base to learn from my mistakes. It was useful when I needed the endorphines boost of seeing all the progress done. Once I assumed that progress speed and understood that we always do the best we can given how we are, I started to feel that the review process was too cumbersome and that it was holding me into the past.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Nowadays I try not to look back but forward, analyze the present: how I feel, how&#39;s the environment around me, and how can I tweak both to fulfill my life goals. This approach leads to less reviewing of achievements and logs and more introspection, thinking and imagining. Which although may be slower to correct mistakes of the past, will surely make you live closer to the utopy.&lt;/p&gt; &lt;p&gt;The reviews below then follow that second approach.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Personal alive reviews: Reviews have to reflect ourselves, and we change continuously, so take for granted that your review is going to change.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;I&#39;ve gone for full blown reviews of locking myself up for a week to not doing reviews for months.&lt;/p&gt; &lt;p&gt;This article represent the guidelines I follow to do my life review. It may seem a lot to you or may be very simple. Please take it as a base or maybe to get some ideas and then create your own that fits your needs.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Update the Month review process.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: When to do the trimester reviews.&lt;/p&gt; &lt;p&gt;As with &lt;a href=&#34;life_review.md#month-review&#34;&gt;moth reviews&lt;/a&gt;, it&#39;s interesting to do analysis at representative moments. It gives it an emotional weight. You can for example use the solstices or my personal version of the solstices:&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Spring analysis (1&lt;sup&gt;st&lt;/sup&gt; of March): For me the spring is the real start of the year, it&#39;s when life explodes after the stillness of the winter. The sun starts to set later enough so that you have light in the afternoons, the climate gets warmer thus inviting you to be more outside, the nature is blooming new leaves and flowers. It is then a moment to build new projects and set the current year on track.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Summer analysis (1&lt;sup&gt;st&lt;/sup&gt; of June): I hate heat, so summer is a moment of retreat. Everyone temporarily stop their lives, we go on holidays and all social projects slow their pace. Even the news have even less interesting things to report. It&#39;s so hot outside that some of us seek the cold refuge of home or remote holiday places. Days are long and people love to hang out till late, so usually you wake up later, thus having less time to actually do stuff. Even in the moments when you are alone the heat drains your energy to be productive. It is then a moment to relax and gather forces for the next trimester. It&#39;s also perfect to develop &lt;em&gt;easy&lt;/em&gt; and &lt;em&gt;chill&lt;/em&gt; personal projects that have been forgotten in a drawer. Lower your expectations and just flow with what your body asks you.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Autumn analysis (1&lt;sup&gt;st&lt;/sup&gt; of September): September it&#39;s another key moment for many people. We have it hardcoded in our life since we were children as it was the start of school. People feel energized after the summer holidays and are eager to get back to their lives and stopped projects. You&#39;re already 6 months into the year, so it&#39;s a good moment to review your year plan and decide how you want to invest your energy reserves.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Winter analysis (1&lt;sup&gt;st&lt;/sup&gt; of December): December is the cue that the year is coming to an end. The days grow shorter and colder, they basically invite you to enjoy a cup of tea under a blanket. It is then a good time to get into your cave and do an introspection analysis on the whole year and prepare the ground for the coming year. Some of the goals of this season are:&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Think everything you need to guarantee a good, solid and powerful spring start.&lt;/li&gt; &lt;li&gt;Do the year review to adjust your principles.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The year is then divided in two sets of an expansion trimester and a retreat one. We can use this information to adjust our life plan accordingly. In the expansion trimester we could invest more energies in the planning, and in the retreat ones we can do more throughout reviews.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: The principle documents.&lt;/p&gt; &lt;p&gt;Principle documents for me are &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/&#34;&gt;orgmode&lt;/a&gt; documents where I think about the principle itself. It acts both as a way of understanding it and evolving my idea around it, and to build the roadmap to materialize the principle&#39;s path.&lt;/p&gt; &lt;p&gt;Without ever having created one I feel that it makes sense to make the reflection part public in the blue book, while I keep for myself the private one. This may also change between principles.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: The life path document.&lt;/p&gt; &lt;p&gt;The life path document is an &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/&#34;&gt;orgmode&lt;/a&gt; document where I think about what I want to do with my life and how. It&#39;s the highest level of abstraction of the life management system.&lt;/p&gt; &lt;p&gt;The structure so far is as follows:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;* Life path
** {year}
*** Principles of {season} {year}
    {Notes on the season}
    - Principle 1
    - Principle 2
    ...

**** Objectives of {month} {year}
     - [-] Objective 1
       - [X] SubObjective 1
       - [ ] SubObjective 2
     - [ ] Objective 2
     - [ ] ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where the principles are usually links to principle documents and the objectives links to tasks.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Trimester prepare.&lt;/p&gt; &lt;p&gt;The trimester review requires an analysis that doesn&#39;t fill in a day session. It requires slow thinking over some time. So I&#39;m creating a task 10 days before the actual review to start thinking about the next trimester. Whether it&#39;s ideas, plans, desires, objectives, or principles.&lt;/p&gt; &lt;p&gt;Is useful for that document to be available wherever you go, so that in any spare time you can pop it up and continue with the train of thought.&lt;/p&gt; &lt;p&gt;Doing the reflection without seeing your life path prevents you from being tainted by it, thus representing the real you of right now.&lt;/p&gt; &lt;p&gt;On the day to actually do the review, follow the steps of the &lt;a href=&#34;life_review.md#month-prepare&#34;&gt;Month review prepare&lt;/a&gt; adjusting them to the trimester case.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Update the month planning.&lt;/p&gt; &lt;p&gt;Decide the month objectives:&lt;/p&gt; &lt;p&gt;Create the month objectives in your roadmap file after addressing each element of:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Your last month review document.&lt;/li&gt; &lt;li&gt;The trimester objectives of your roadmap.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Once they are ready, copy them to the description of your &lt;code&gt;todo.org&lt;/code&gt; file. That way you&#39;ll see it every day.&lt;/p&gt; &lt;p&gt;For each of your month objectives:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Decide whether it makes sense to address it this month. If not, archive it&lt;/li&gt; &lt;li&gt;Create a clear plan of action for this month on that objective&lt;/li&gt; &lt;li&gt;Define the todo of each device (mobile, tablet, laptop)&lt;/li&gt; &lt;li&gt;Tweak your &lt;em&gt;things to think about list&lt;/em&gt;.&lt;/li&gt; &lt;li&gt;Tweak your &lt;em&gt;reading list&lt;/em&gt;.&lt;/li&gt; &lt;li&gt;Tweak your week distribution (what to do in each day)&lt;/li&gt; &lt;li&gt;If you selected maintenance week days tweak the priorities on your &lt;em&gt;maintenance list&lt;/em&gt;.&lt;/li&gt; &lt;li&gt;If you selected improvement week days tweak the priorities on your &lt;em&gt;improvements list&lt;/em&gt;.&lt;/li&gt; &lt;li&gt;Tweak your &lt;em&gt;habit manager system&lt;/em&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Use deadlines.&lt;/p&gt; &lt;p&gt;Identify hard deadlines: Add a warning days before the deadline to make sure you&#39;re reminded until it&#39;s done.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add 2024 Hidden Cup 5 awesome match.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://yewtu.be/watch?v=Ol-mqMeQ7OQ&#34;&gt;Semifinal Viper vs Lierey&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Prometheus metrics.&lt;/p&gt; &lt;p&gt;Use &lt;a href=&#34;https://github.com/trallnag/prometheus-fastapi-instrumentator&#34;&gt;&lt;code&gt;prometheus-fastapi-instrumentator&lt;/code&gt;&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Tweak the month planning.&lt;/p&gt; &lt;p&gt;Add the next steps:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Clean your agenda and get an feeling of the busyness of the month:&lt;/li&gt; &lt;li&gt;Open the orgmode month view agenda and clean it&lt;/li&gt; &lt;li&gt;Read the rest of your calendars&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Then reorder the objectives in order of priority. Try to have at least one objective that improves your life.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;For each of your month and trimester objectives:&lt;/li&gt; &lt;li&gt;Decide whether it makes sense to address it this month. If not, mark it as inactive&lt;/li&gt; &lt;li&gt; &lt;p&gt;Create a clear plan of action for this month on that objective.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Reorder the projects as needed&lt;/li&gt; &lt;li&gt;Mark as INACTIVE the ones that you don&#39;t feel need to be focused on this month.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Refine the roadmap of each of the selected areas (change this to the trimestral planning)&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Select at least one coding project in case you enter in programming mode&lt;/li&gt; &lt;li&gt;Clean your mobile browser tabs&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Deprecate not-by-ai.&lt;/p&gt; &lt;p&gt;As they have introduced pricing, which makes no sense, and we had a discussion that using that badge it&#39;s a nice way to tell the AI which content to use and which not to&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Reorganization: Into roadmap_adjustment.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;aside class=&#34;md-source-file&#34;&gt; &lt;span class=&#34;md-source-file__fact&#34;&gt; &lt;span class=&#34;md-icon&#34; title=&#34;Last update&#34;&gt; &lt;svg viewbox=&#34;0 0 24 24&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z&#34;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt; &lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago&#34; title=&#34;January 1, 2025 06:45:54 UTC&#34;&gt;&lt;span class=&#34;timeago&#34; datetime=&#34;2025-01-01T06:45:54+00:00&#34; locale=&#34;en&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date&#34; title=&#34;January 1, 2025 06:45:54 UTC&#34;&gt;2025-01-01&lt;/span&gt; &lt;/span&gt; &lt;/aside&gt; &lt;/article&gt;</description>
      <link>https://lyz-code.github.io/blue-book/newsletter/2024/</link>
      <pubDate>2025-01-01 06:45:54+00:00</pubDate>
      <source url="https://lyz-code.github.io/blue-book/yearly.xml">The Blue Book</source>
      <guid isPermaLink="true">https://lyz-code.github.io/blue-book/newsletter/2024/</guid>
      
    </item>
    
    <item><title>2023</title>
      <author>Lyz</author>
      <description>&lt;article class=&#34;md-content__inner md-typeset&#34;&gt;  &lt;h2 id=&#34;activism&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/anticolonialism/&#34;&gt;Activism&lt;/a&gt;&lt;/h2&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add song for Gaza.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://yewtu.be/watch?v=dlfhoU66s4Y&#34;&gt;We Will Not Go Down (Song for Gaza Palestine) - Michael Heart&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;collaborating-tools&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/collaborating_tools/&#34;&gt;Collaborating tools&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce collaborating tools.&lt;/p&gt; &lt;p&gt;Collaborating document creation:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://pad.riseup.net&#34;&gt;https://pad.riseup.net&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://rustpad.io&#34;&gt;https://rustpad.io&lt;/a&gt; . &lt;a href=&#34;https://github.com/ekzhang/rustpad&#34;&gt;Can be self hosted&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Collaborating through terminals:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://sshx.io/&#34;&gt;sshx&lt;/a&gt; looks promising although I think it uses their servers to do the connection, which is troublesome.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;life-management&#34;&gt;Life Management&lt;/h2&gt; &lt;h3 id=&#34;life-management_1&#34;&gt;Life Management&lt;/h3&gt; &lt;h4 id=&#34;life-planning&#34;&gt;&lt;a href=&#34;life_planning.md&#34;&gt;Life planning&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;life_planning.md#month-plan&#34;&gt;Introduce the month planning process.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The objectives of the month plan are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Define the month objectives according to the trimester plan and the insights gathered in the past month review.&lt;/li&gt; &lt;li&gt;Make your backlog and todo list match the month objectives&lt;/li&gt; &lt;li&gt;Define the philosophical topics to address&lt;/li&gt; &lt;li&gt;Define the topics to learn&lt;/li&gt; &lt;li&gt;Define the are of habits to incorporate?&lt;/li&gt; &lt;li&gt;Define the checks you want to do at the end of the month.&lt;/li&gt; &lt;li&gt;Plan when is it going to be the next review.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;It&#39;s interesting to do the plannings on meaningful days such as the first one of the month. Usually we don&#39;t have enough flexibility in our life to do it exactly that day, so schedule it the closest you can to that date. It&#39;s a good idea to do both the review and the planning on the same day.&lt;/p&gt; &lt;p&gt;We&#39;ll divide the planning process in these phases:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Prepare&lt;/li&gt; &lt;li&gt;Clarify your state&lt;/li&gt; &lt;li&gt;Decide the month objectives&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Prepare:&lt;/p&gt; &lt;p&gt;It&#39;s important that you prepare your environment for the planning. You need to be present and fully focused on the process itself. To do so you can:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Make sure you don&#39;t get interrupted:&lt;ul&gt; &lt;li&gt;Check your task manager tools to make sure that you don&#39;t have anything urgent to address in the next hour.&lt;/li&gt; &lt;li&gt;Disable all notifications&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Set your analysis environment:&lt;ul&gt; &lt;li&gt;Put on the music that helps you get &lt;em&gt;in the zone&lt;/em&gt;.&lt;/li&gt; &lt;li&gt;Get all the things you may need for the review:&lt;ul&gt; &lt;li&gt;The checklist that defines the process of your planning (this document in my case).&lt;/li&gt; &lt;li&gt;Somewhere to write down the insights.&lt;/li&gt; &lt;li&gt;Your task manager system&lt;/li&gt; &lt;li&gt;Your habit manager system&lt;/li&gt; &lt;li&gt;Your &lt;em&gt;Objective list&lt;/em&gt;.&lt;/li&gt; &lt;li&gt;Your &lt;em&gt;Thinking list&lt;/em&gt;.&lt;/li&gt; &lt;li&gt;Your &lt;em&gt;Reading list&lt;/em&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Remove from your environment everything else that may distract you&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Clarify your state:&lt;/p&gt; &lt;p&gt;To be able to make a good decision on your month&#39;s path you need to sort out which is your current state. To do so:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Clean your inbox: Refile each item until it&#39;s empty&lt;/li&gt; &lt;li&gt;Clean your todo: Review each todo element by deciding if they should still be in the todo. If they do and they belong to a month objective, add it. If they don&#39;t need to be in the todo, refile it.&lt;/li&gt; &lt;li&gt;Clean your someday: Review each relevant someday element (not the ones that are archive at greater levels than month) and decide if they should be refiled elsewhere and if they are part of a month objective that should be dealt with this month.&lt;/li&gt; &lt;li&gt;Adress each of the trimester objectives by creating month objectives that get you closer to the desired objective.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Decide the next steps:&lt;/p&gt; &lt;p&gt;For each of your month objectives:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Decide wheter it makes sense to address it this month. If not, archive it&lt;/li&gt; &lt;li&gt;Create a clear plan of action for this month on that objective&lt;/li&gt; &lt;li&gt;Tweak your &lt;em&gt;things to think about list&lt;/em&gt;.&lt;/li&gt; &lt;li&gt;Tweak your &lt;em&gt;reading list&lt;/em&gt;.&lt;/li&gt; &lt;li&gt;Tweak your &lt;em&gt;habit manager system&lt;/em&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;task-management&#34;&gt;Task Management&lt;/h3&gt; &lt;h4 id=&#34;org-mode&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/&#34;&gt;Org Mode&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Nvim Org Mode.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/nvim-orgmode/orgmode#agenda&#34;&gt;&lt;code&gt;nvim-orgmode&lt;/code&gt;&lt;/a&gt; is a Orgmode clone written in Lua for Neovim. Org-mode is a flexible note-taking system that was originally created for Emacs. It has gained wide-spread acclaim and was eventually ported to Neovim.&lt;/p&gt; &lt;p&gt;The article includes:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#installation&#34;&gt;Installation&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#key-bindings&#34;&gt;Key bindings&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#usage&#34;&gt;Usage&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#org-file&#34;&gt;Org File&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#headings&#34;&gt;Headings&lt;/a&gt;&lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#toogle-line-to-headline&#34;&gt;Toogle line to headline&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#change-heading-level&#34;&gt;Change heading level&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#moving-headings&#34;&gt;Moving headings&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#folding-headings&#34;&gt;Folding headings&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#navigate-through-headings&#34;&gt;Navigate through headings&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#todo-items&#34;&gt;TODO items&lt;/a&gt;&lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#todo-state-customization&#34;&gt;TODO state customization&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#priority&#34;&gt;Priority&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#dates&#34;&gt;Dates&lt;/a&gt;&lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#appointments&#34;&gt;Appointments&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#recurring-tasks&#34;&gt;Recurring tasks&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#scheduled&#34;&gt;Scheduled&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#deadline&#34;&gt;Deadline&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#date-management&#34;&gt;Date management&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#tags&#34;&gt;Tags&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#lists&#34;&gt;Lists&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#checkboxes&#34;&gt;Checkboxes&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#links&#34;&gt;Links&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#archiving&#34;&gt;Archiving&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#refiling&#34;&gt;Refiling&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#agend&#34;&gt;Agenda&lt;/a&gt;&lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#moving-around-the-agenda&#34;&gt;Move around the agenda&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#act-on-the-agenda-elements&#34;&gt;Act on the agenda elements&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#agenda-views&#34;&gt;Agenda views&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#capture-all-your-stuff&#34;&gt;Capture all your stuff.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The focus of this process is to capture &lt;em&gt;everything&lt;/em&gt; that has your attention, otherwise some part of you will still not totally trust that you&#39;re working with the whole picture. While you&#39;re doing it, create a list of all the sources of inputs in your world.&lt;/p&gt; &lt;p&gt;What you&#39;re going to do is methodically go through each piece of your life and search for anything that doesn’t permanently belong where it is, the way it is, and put it into your in-tray. You’ll be gathering things that are incomplete or things that have some decision about potential action tied to them. They all go into your “inbox”, so they’ll be available for later processing.&lt;/p&gt; &lt;p&gt;Be patient, this process may take between 1 and 6 hours, and at the end you&#39;ll have a huge pile of stuff in your inbox. You might be scared and get the thought of &#34;what am I doing with my life?&#34;, but don&#39;t worry you&#39;ll get everything in order soon :).&lt;/p&gt; &lt;p&gt;The steps described in the section so far are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#define-what-is-going-to-be-your-in-tray&#34;&gt;Define what is going to be your in-tray&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#physical-gathering&#34;&gt;Physical gathering&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#digital-general-reference&#34;&gt;Digital general reference.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It is very helpful to have a visual map sorted in ways that make sense, either by indexes or data groups organized effectively, usually in an alphabetic order.&lt;/p&gt; &lt;p&gt;The biggest issue for digitally oriented people is that the ease of capturing and storing has generated a write-only syndrome: all they’re doing is capturing information—not actually accessing and using it intelligently. Some consciousness needs to be applied to keep one’s potentially huge digital library functional, versus a black hole of data easily dumped in there with a couple of keystrokes.&lt;/p&gt; &lt;p&gt;You need to consistently check how much room to give yourself so that the content remains meaningfully and easily accessible, without creating a black hole of an inordinate amount of information amorphously organized.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#physical-general-reference&#34;&gt;Physical general reference.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;One idea is to have one system/place where you order the content alphabetically, not multiple ones. People have a tendency to want to use their files as a personal management system, and therefore they attempt to organize them in groupings by projects or areas of focus. This magnifies geometrically the number of places something isn’t when you forget where you filed it.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#refiling&#34;&gt;Use telescope plugin for refiling.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Refiling lets you easily move around elements of your org file, such as headings or TODOs. You can refile with &lt;code&gt;&amp;lt;leader&amp;gt;r&lt;/code&gt; with the next snippet:&lt;/p&gt;  &lt;p&gt;When you press the refile key binding you are supposed to press &lt;code&gt;&amp;lt;tab&amp;gt;&lt;/code&gt; to see the available options, once you select the correct file, if you will be shown a autocomplete with the possible items to refile it to. Luckily there is &lt;a href=&#34;https://github.com/joaomsa/telescope-orgmode.nvim&#34;&gt;a Telescope plugin&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Install it by adding to your plugin config:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;joaomsa/telescope-orgmode.nvim&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then install it with &lt;code&gt;:PackerInstall&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;You can setup the extension by doing:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;telescope&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;load_extension&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;orgmode&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To replace the default refile prompt:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_create_autocmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;FileType&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;pattern&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;org&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;group&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_create_augroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;orgmode_telescope_nvim&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;clear&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;callback&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;r&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;telescope&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;extensions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;orgmode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;refile_heading&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;g&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;telescope&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;extensions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;orgmode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;search_headings&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If the auto command doesn&#39;t override the default &lt;code&gt;orgmode&lt;/code&gt; one, bind it to another keys and never use it.&lt;/p&gt; &lt;p&gt;The plugin also allows you to use &lt;code&gt;telescope&lt;/code&gt; to search through the headings of the different files with &lt;code&gt;search_headings&lt;/code&gt;, with the configuration above you&#39;d use &lt;code&gt;&amp;lt;leader&amp;gt;g&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#todo-list&#34;&gt;Define the Todo list.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This list contains all the next actions and projects you are going to actively work on. Projects are any desired result that can be accomplished within a year that requires more than one action step. This means that some rather small things you might not normally call projects are going to be on your Projects list, as well as some big ones. If one step won’t complete something, some kind of goalpost needs to be set up to remind you that there’s something still left to do. If you don’t have a placeholder to remind you about it, it will slip back into your head. The reason for the one-year time frame is that anything you are committed to finish within that scope needs to be reviewed weekly to feel comfortable about its status. Another way to think of this is as a list of open loops, no matter what the size. This is going to be one of the lists that you&#39;ll review more often, and it needs to be manageable, if the items start to grow you may want to track the elements you want to do in the semester, or trimester.&lt;/p&gt; &lt;p&gt;Projects do not initially need to be listed in any particular order, by size, or by priority. They just need to be on a master list so you can review them regularly enough to ensure that appropriate next actions have been defined for each of them. That being said, I like to order them a little bit so that I don&#39;t need to read the whole list to choose what to do.&lt;/p&gt; &lt;p&gt;There may be reasons to sort your projects into different subcategories, based upon different areas of your focus, but initially creating a single list of all of them will make it easier to customize your system appropriately as you get more comfortable with its usage. To sort them use tags instead of hierarchical structures, they are more flexible. For example you could use tags for:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Context: Where can you do the element: &lt;code&gt;home&lt;/code&gt;, &lt;code&gt;computer&lt;/code&gt;, &lt;code&gt;mobile&lt;/code&gt;, ...&lt;/li&gt; &lt;li&gt;Area: Broad categories where the element falls in: &lt;code&gt;activism&lt;/code&gt;, &lt;code&gt;caring&lt;/code&gt;, &lt;code&gt;self-caring&lt;/code&gt;, &lt;code&gt;home&lt;/code&gt;, &lt;code&gt;digital services&lt;/code&gt;, ...&lt;/li&gt; &lt;li&gt;Type: I like to separate the tasks that are meant to survive (&lt;code&gt;maintenance&lt;/code&gt;) from the ones that are meant to improve things (&lt;code&gt;improvement&lt;/code&gt;)&lt;/li&gt; &lt;li&gt;Mood, energy level, time: It&#39;s useful to have a quick way to see the tasks you can work on when you don&#39;t have that much time (&lt;code&gt;small&lt;/code&gt;), you don&#39;t have that much mental energy (&lt;code&gt;brainless&lt;/code&gt;), when you&#39;re &lt;code&gt;sad&lt;/code&gt;, ...&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;For many of your projects, you will accumulate relevant information that you will want to organize by theme or topic or project name. Your Projects list will be merely an index. All of the details, plans, and supporting information that you may need as you work on your various projects should be contained in your References system.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#calendar&#34;&gt;Define the calendar.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The calendar holds reminders of actions you need to take fall into two categories: those about things that have to happen on a specific day or time, and those about things that just need to get done as soon as possible. Your calendar handles the first type of reminder.&lt;/p&gt; &lt;p&gt;These things go on your calendar:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Time-Specific actions or appointments.&lt;/li&gt; &lt;li&gt;Day-Specific actions: These are things that you need to do sometime on a certain day, but not necessarily at a specific time.&lt;/li&gt; &lt;li&gt;Day-Specific information: Information that may be useful on a certain date. This might include directions for appointments, activities that other people will be involved in then, or events of interest. It’s helpful to put short-term tickler information here, too, such as a reminder to call someone after he or she returns from vacation. This is also where you would want to park important reminders about when something might be due, or when something needs to be started, given a determined lead time.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Daily to-do lists don&#39;t belong to the calendar because:&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Constant new input and shifting tactical priorities reconfigure daily work so consistently that it’s virtually impossible to nail down to-do items ahead of time. Having a working game plan as a reference point is always useful, but it must be able to be renegotiated at any moment. Trying to keep a list on the calendar, which must then be reentered on another day if items don’t get done, is demoralizing and a waste of time. The Next Actions lists will hold all of those action reminders, even the most time-sensitive ones. And they won’t have to be rewritten daily.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;If there’s something on a daily to-do list that doesn’t absolutely have to get done that day, it will dilute the emphasis on the things that truly do. The calendar should be sacred territory. If you write something there, it must get done that day or not at all.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;That said, there’s absolutely nothing wrong with creating a quick, informal, short list of “if I have time, I’d really like to . . .” kinds of things, picked from your Next Actions inventory. It just should not be confused with your “have-tos,” and it should be treated lightly enough to discard or change quickly as the inevitable surprises of the day unfold.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#design-your-system&#34;&gt;Give an overview of how I&#39;m using gtd.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Before you start moving stuff around it&#39;s a good idea to get the first design of your whole system, in my case I&#39;m going to heavily rely on org-mode to track most of the stuff with a repository with the next structure:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;.
├── calendar
│   ├── personal.org
│   │   ├── One time events
│   │   ├── Recurring events
│   │   ├── Birthdays
│   │   └── Deathdays
│   ├── day.org
│   ├── tickler.org
│   ├── work_1.org
│   ├── work_2.org
│   ├── partner.org
│   ├── family.org
├── inbox
│   ├── computer.org
│   ├── mobile.org
│   └── tablet.org
├── reference
│   ├── blue
│   ├── reference.org
│   └── red
└── todo
    ├── personal.org
    ├── work_1.org
    ├── work_2.org
    └── someday.org
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The subtrees behind the &lt;code&gt;.org&lt;/code&gt; files are the heading trees.&lt;/li&gt; &lt;li&gt;All &lt;code&gt;org&lt;/code&gt; files go with their respective &lt;code&gt;org_archive&lt;/code&gt; ones, they&#39;re not shown in the above diagram to keep it simple.&lt;/li&gt; &lt;li&gt;&lt;code&gt;calendar/personal.org&lt;/code&gt; is my &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#personal-calendar&#34;&gt;personal calendar&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;code&gt;calendar/day.org&lt;/code&gt; is my &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#day-planner&#34;&gt;day planner&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#personal-calendar&#34;&gt;Define how to use the Personal calendar.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The &lt;code&gt;calendar/personal.org&lt;/code&gt; file holds:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#appointments&#34;&gt;Appointments&lt;/a&gt;: Meant to be used for elements of the org file that have a defined date to occur. You whether do it that date or not do it at all. Avoid using dates to organize your tasks and if you don&#39;t do it that day, reschedule it to another date, it&#39;s a waste of time, use next actions in your &lt;code&gt;todo&lt;/code&gt; instead. If you need to act on it use a &lt;code&gt;TODO&lt;/code&gt; element, otherwise a headline is enough An example would be.&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;* TODO Meet with Marie
&amp;lt;2023-02-24 Fri&amp;gt;

* Internet&#39;s birthday
&amp;lt;2023-03-13 Mon&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#recurring-tasks&#34;&gt;Recurring events&lt;/a&gt;: Events that not only happen on the given date, but again and again after a certain interval of N hours (h), days (d), weeks (w), months (m), or years (y). The following shows up in the agenda every Wednesday:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;* TODO Go to pilates
  &amp;lt;2007-05-16 Wed 12:30 +1w&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;#tickler-management&#34;&gt;Tickler events&lt;/a&gt;: Check the &lt;a href=&#34;#tickler-management&#34;&gt;Tickler management&lt;/a&gt; section for more details.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Each section has it&#39;s own tag: &lt;code&gt;:recurring:&lt;/code&gt;, &lt;code&gt;:day:&lt;/code&gt;, &lt;code&gt;:birthday:&lt;/code&gt;, &lt;code&gt;:deathday:&lt;/code&gt;, and the whole file has the &lt;code&gt;:event:&lt;/code&gt; tag for easy filtering.&lt;/p&gt; &lt;p&gt;In rare cases you may want to use the &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#deadline&#34;&gt;&lt;code&gt;DEADLINE&lt;/code&gt;&lt;/a&gt; property if you want to be warned in the agenda some days before the date arrives or the &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#scheduled&#34;&gt;&lt;code&gt;SCHEDULED&lt;/code&gt;&lt;/a&gt; one in case you want to see in the agenda when you start working on the task. Again, don&#39;t waste time postponing these dates, if you do, you&#39;re using the system wrong.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#day-planner&#34;&gt;Define how to use the Day planner.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Some of my day events are semi-regular, meaning that the recurrence options are not powerful enough. For example, I usually go to pilates on Tuesdays, but some weeks I go at 18:00 and others at 19:00. In the past I used a script that interacts with &lt;a href=&#34;https://lyz-code.github.io/blue-book/khal/&#34;&gt;&lt;code&gt;ikhal&lt;/code&gt;&lt;/a&gt; to create the elements of the day based on some questionary. The idea is to migrate the tool to create appointments in the day under the &lt;code&gt;diary.org&lt;/code&gt; file using a &lt;code&gt;datetree&lt;/code&gt; structure:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;* 2010
** 2010-12 December
*** 2010-12-20 Tuesday
**** TODO Go to pilates
    &amp;lt;2010-12-20 Tue 19:00-20:00&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;I also use this file to add any diary annotations for my &lt;a href=&#34;https://lyz-code.github.io/blue-book/life_logging/&#34;&gt;life log&lt;/a&gt;. Once &lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/issues/516&#34;&gt;this issue is solved&lt;/a&gt; it will be really easy to add diary thoughts through the &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#capture&#34;&gt;capture feature&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#todo-files&#34;&gt;Define how to use the todo files.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The &lt;code&gt;todo&lt;/code&gt; files are where you track the &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#todo-list&#34;&gt;todo list&lt;/a&gt;, which holds your projects and their next steps to work on. The &lt;code&gt;todo/personal.org&lt;/code&gt;, &lt;code&gt;todo/work_1.org&lt;/code&gt; and &lt;code&gt;todo/work_2.org&lt;/code&gt; files of &lt;a href=&#34;#design-your-system&#34;&gt;the above schema&lt;/a&gt; will be divided into these level 1 headings:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;* Necessary&lt;/code&gt;: These projects need to be dealt with immediately and finished as soon as possible&lt;/li&gt; &lt;li&gt;&lt;code&gt;* Desirable&lt;/code&gt;: Here is where most of your elements will be, these are the ones that you think it&#39;s important to work on but there is no hard pressure.&lt;/li&gt; &lt;li&gt;&lt;code&gt;* Optional&lt;/code&gt;: These are the projects that it would be nice to work on, but if you don&#39;t it&#39;s fine.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Projects are any the second level headings with TODO keywords. To see the list of your projects just fold all the items in the &lt;code&gt;todo.org&lt;/code&gt; file.&lt;/p&gt; &lt;p&gt;Inside each section the elements are more less ordered by what I want to work on first. But all projects are actionable, so if I&#39;m not in the mood to do the first ones, I tackle the rest. As such, I try not to spend too much time ordering them.&lt;/p&gt; &lt;p&gt;I find useful to split the tasks between my life silos, so that I don&#39;t even have a chance to think of anything of &lt;code&gt;work_1&lt;/code&gt; when I&#39;m doing my &lt;code&gt;personal&lt;/code&gt; stuff or &lt;code&gt;work_2&lt;/code&gt; stuff.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#project-structure&#34;&gt;Define how to work with projects.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Given the broad definition of what we consider a project and how they are usually cooked, the system that represents it must be equally flexible, quick to interact with and easy to evolve.&lt;/p&gt; &lt;p&gt;Every project starts with the title:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;* TODO Improve task management system
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Optionally you can add a description&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;* TODO Improve task management system
  Using Openprojects is uncomfortable, I need to find a better system.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You may have noticed that the description doesn&#39;t follow the rules we defined for next actions, that&#39;s fine as you don&#39;t act on projects, but on their underlying actions. Nevertheless I like to start them with a verb. It may even make sense not to use TODO items but simple headings to define your projects. On one side you don&#39;t act on projects so it would make sense to use headings, on the other, it&#39;s also interesting to know the project state, which can be easily tracked with the TODO keywords. If you could tell apart headings from TODO items in the &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#agenda&#34;&gt;agenda&lt;/a&gt; views it would make sense to use them. Right now &lt;code&gt;nvim-orgmode&lt;/code&gt; let&#39;s you select in the agenda views only TODO items or TODO and headings, but you can&#39;t select only headings, so at the moment I don&#39;t see any good reason not to use TODO items for the projects.&lt;/p&gt; &lt;p&gt;To define the next actions of a project you can use checklists&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;* TODO Improve task management system
  - [-] Read David Allen&#39;s GTD book
    - [x] Read chapters 6 and 7
    - [ ] Read chapters 8 and 9
  - [ ] Sum up the book in the blue book
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;As your checklists grow they may start to be uncomfortable, for example if it has:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;More than two levels of indentation: It may be hard to follow the logic of the task structure.&lt;/li&gt; &lt;li&gt;A lot of elements: You can&#39;t archive parts of checklists, so as you complete elements, they will still be shown diverting your attention from the things you can actually act upon or making you loose time scrolling to find where they are.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;In these cases it makes sense to promote the first level of headings to subprojects:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;* TODO Improve task management system
  * DOING Read David Allen&#39;s GTD book
    - [x] Read chapters 6 and 7
    - [ ] Read chapters 8 and 9
  * TODO up the book in the blue book
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;That way when &lt;code&gt;Read David Allen&#39;s GTD book&lt;/code&gt; is done, you can archive it and forget about it.&lt;/p&gt; &lt;p&gt;If the project starts having many subprojects, it may help to have a section &#34;Outcomes&#34; to define what do you want to achieve with the project. It can be accompanied with a &#34;Next Steps&#34; section to add any subproject or action that doesn&#39;t match the defined outcomes, and once you finish the project, you can refile them into new projects.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#the-next-state&#34;&gt;The NEXT state.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It&#39;s useful to have a &lt;code&gt;NEXT&lt;/code&gt; state to track the first next action you need to deal with for each project. That way when you open the file, you can go to the top of it and search for &lt;code&gt;NEXT&lt;/code&gt; and it will lead you directly to where you need to work on.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#tag-management&#34;&gt;Define how to manage tags.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;As explained in the &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#todo-list&#34;&gt;todo list&lt;/a&gt; section, you can use tags to filter your tasks. I&#39;m using the next ones:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Area: Broad categories where the element falls in: &lt;code&gt;activism&lt;/code&gt;, &lt;code&gt;caring&lt;/code&gt;, &lt;code&gt;self-caring&lt;/code&gt;, &lt;code&gt;home&lt;/code&gt;, &lt;code&gt;digital services&lt;/code&gt;, ...&lt;/li&gt; &lt;li&gt;Type: I like to separate the tasks that are meant to survive (&lt;code&gt;maintenance&lt;/code&gt;) from the ones that are meant to improve things (&lt;code&gt;improvement&lt;/code&gt;). I use these only in the big projects.&lt;/li&gt; &lt;li&gt;&lt;code&gt;:long_break:&lt;/code&gt;: I&#39;m using this tag to track the small projects that can be done in the &lt;a href=&#34;life_planning.md&#34;&gt;long pomodoro breaks&lt;/a&gt;. Depending on the kind of long break that I need I then filter for the next tags:&lt;/li&gt; &lt;li&gt;&lt;code&gt;brainless&lt;/code&gt;: If I want to keep on thinking on what I was doing, an example could be emptying the dishwasher, watering the plants, ...&lt;/li&gt; &lt;li&gt;&lt;code&gt;call&lt;/code&gt;: If I want to completely change context and want some social interaction. For example call mom.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#waiting-tasks&#34;&gt;Define how to manage waiting tasks.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Waiting actions are elements that are blocked for any reason. I use the &lt;code&gt;WAITING&lt;/code&gt; TODO keyword to track this state. Under each element you should add that reason and optionally the process you want to follow to unblock it.&lt;/p&gt; &lt;p&gt;If you need to actively track the evolution of the WAITING status, leave it on the top of your &lt;code&gt;todo&lt;/code&gt;. Otherwise set the date you want to check its status and move it to the &lt;code&gt;ticker.org&lt;/code&gt; file.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#tickler-management&#34;&gt;Define how to use the tickler.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The tickler is a system where you postpone actions to a specific date, but not with a calendar mindset where the action &lt;strong&gt;needs&lt;/strong&gt; to be done at that date. With the tickler you schedule the action to enter your inbox that day to decide what are you going to do with it.&lt;/p&gt; &lt;p&gt;To implement this in orgmode you can add the &lt;code&gt;:tickler:&lt;/code&gt; tag to any element that is tracked in the agenda files and once a day you can look at the day&#39;s agenda and decide what to do with the action. It&#39;s important though that whatever you do with it, you have to remove it from the agenda view in order to only keep the elements that you need to do in the day. You can follow this workflow by:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Opening the agenda view &lt;code&gt;gaa&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Go to the view of the day &lt;code&gt;vd&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Go to today &lt;code&gt;.&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Search by tickler &lt;code&gt;/tickler&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;It can also help to review in the weeklies all the ticklers of the week to avoid surprises.&lt;/p&gt; &lt;p&gt;If you want to make the project go away from your &lt;code&gt;todo&lt;/code&gt; or &lt;code&gt;someday&lt;/code&gt; until the tickler date, move it to the &lt;code&gt;tickler.org&lt;/code&gt; file.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#capture-all-your-stuff&#34;&gt;Keep on defining steps to capture all your stuff.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;As you engage in the capturing step, you may run into one or more of the following problems:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;An item is too big to go in the in-tray: create a post it that represents it or add it as an entry in your digital inbox. If you can, add the date too&lt;/li&gt; &lt;li&gt;The pile is too big to fit the in-tray: Create visually distinct stacks around the in-tray, even on the floor.&lt;/li&gt; &lt;li&gt;Doubts whether to trash something: When in doubt keep it, you&#39;ll decide about it later when you process the in-tray. What you need to avoid is to get caught up in deciding what to do with the element. That&#39;s going to be the next step in the process, let&#39;s go one at a time.&lt;/li&gt; &lt;li&gt;Getting caught up in cleaning and organizing: If it doesn&#39;t take that long it&#39;s fine but remember the purpose of this process and the fact that we want to finish it as soon as possible. If you discover things you want to change, add them to the in-tray.&lt;/li&gt; &lt;li&gt;If you encounter stuff that is already on lists and organizers, treat them as everything else in the &#34;in&#34;.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Now that the process it&#39;s clear let&#39;s start.&lt;/p&gt; &lt;p&gt;Start with the space where you actually do stuff, scan the place centimeter by centimeter with the mindset defined above, check your desk, drawers, floors, walls, shelves, equipment, furniture, fixtures...Then repeat the process with each room of your home.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#mental-gathering&#34;&gt;Explain how to capture all your mental stuff.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Once you already have a nice pile of stuff, think of what has your attention that isn’t represented by something already in your in-tray and record each thought, each idea, each project or thing that occurs you and add it to the inbox.&lt;/p&gt; &lt;p&gt;To assist in clearing your head, you may want to review the &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#mental-gathering&#34;&gt;following the next trigger list&lt;/a&gt;, item by item, to see if you’ve forgotten anything.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Define priorities from A to D.&lt;/p&gt; &lt;p&gt;I feel more comfortable with these priorities:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;A&lt;/code&gt;: Critical&lt;/li&gt; &lt;li&gt;&lt;code&gt;B&lt;/code&gt;: High&lt;/li&gt; &lt;li&gt;&lt;code&gt;C&lt;/code&gt;: Normal&lt;/li&gt; &lt;li&gt;&lt;code&gt;D&lt;/code&gt;: Low&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;This gives you room to usually work on priorities &lt;code&gt;B-D&lt;/code&gt; and if something shows up that is really really important, you can use &lt;code&gt;A&lt;/code&gt;. You can set this setting with the next snippet:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;orgmode&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;org_priority_highest&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;A&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;org_priority_default&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;C&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;org_priority_lowest&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;D&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Warn against using DEADLINE.&lt;/p&gt; &lt;p&gt;Using too many tasks with a &lt;code&gt;DEADLINE&lt;/code&gt; will clutter your agenda. Use it only for the actions that you need to have a reminder, instead try to using &lt;a href=&#34;#appointments&#34;&gt;appointment&lt;/a&gt; dates instead.&lt;/p&gt; &lt;p&gt;If you need a different warning period for a special task, you can specify it. For example setting a warning period of 5 days &lt;code&gt;DEADLINE: &amp;lt;2004-02-29 Sun -5d&amp;gt;&lt;/code&gt;. To configure the default number of days add:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;orgmode&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;org_deadline_warning_days&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#tags&#34;&gt;Improve how to use tags.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;When you press the tag key binding you can type:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;tag1&lt;/code&gt;: It will add &lt;code&gt;:tag1:&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;&lt;code&gt;tag1:tag2&lt;/code&gt;: It will add &lt;code&gt;:tag1:tag2:&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;Press &lt;code&gt;ESC&lt;/code&gt;: It will remove all tags from the item.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Tags make use of the hierarchical structure of outline trees. If a heading has a certain tag, all subheadings inherit the tag as well. For example, in the list&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;* Meeting with the French group      :work:
** Summary by Frank                  :boss:notes:
*** TODO Prepare slides for him      :action:
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The final heading has the tags &lt;code&gt;work&lt;/code&gt;, &lt;code&gt;boss&lt;/code&gt;, &lt;code&gt;notes&lt;/code&gt;, and &lt;code&gt;action&lt;/code&gt; even though the final heading is not explicitly marked with those tags. You can also set tags that all entries in a file should inherit just as if these tags were defined in a hypothetical level zero that surrounds the entire file. Using a line like the next one:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt; #+FILETAGS: :Peter:Boss:Secret:
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#links&#34;&gt;How to use links.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;One final aspect of the org file syntax are links. Links are of the form &lt;code&gt;[[link][description]]&lt;/code&gt;, where link can be an:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#internal-document-links&#34;&gt;Internal reference&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#external-links&#34;&gt;External reference&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;A link that does not look like a URL refers to the current document. You can follow it with &lt;code&gt;gx&lt;/code&gt; when point is on the link (Default &lt;code&gt;&amp;lt;leader&amp;gt;oo&lt;/code&gt;) if you use the next configuration.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;org&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;org_open_at_point&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;gx&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#internal-document-links&#34;&gt;Internal document links.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Org provides several refinements to internal navigation within a document. Most notably:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;[[*Some section]]&lt;/code&gt;: points to a headline with the name &lt;code&gt;Some section&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;&lt;code&gt;[[#my-custom-id]]&lt;/code&gt;: targets the entry with the &lt;code&gt;CUSTOM_ID&lt;/code&gt; property set to &lt;code&gt;my-custom-id&lt;/code&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;When the link does not belong to any of the cases above, Org looks for a dedicated target: the same string in double angular brackets, like &lt;code&gt;&amp;lt;&amp;lt;My Target&amp;gt;&amp;gt;&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;If no dedicated target exists, the link tries to match the exact name of an element within the buffer. Naming is done, unsurprisingly, with the &lt;code&gt;NAME&lt;/code&gt; keyword, which has to be put in the line before the element it refers to, as in the following example&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt; #+NAME: My Target
| a  | table      |
|----+------------|
| of | four cells |
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Ultimately, if none of the above succeeds, Org searches for a headline that is exactly the link text but may also include a &lt;code&gt;TODO&lt;/code&gt; keyword and tags, or initiates a plain text search.&lt;/p&gt; &lt;p&gt;Note that you must make sure custom IDs, dedicated targets, and names are unique throughout the document. Org provides a linter to assist you in the process, if needed, but I have not searched yet one for nvim.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#properties&#34;&gt;How to use properties.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Properties are key-value pairs associated with an entry. They live in a special drawer with the name &lt;code&gt;PROPERTIES&lt;/code&gt;. Each property is specified on a single line, with the key (surrounded by colons) first, and the value after it:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;* CD collection
** Classic
*** Goldberg Variations
    :PROPERTIES:
    :Title:     Goldberg Variations
    :Composer:  J.S. Bach
    :Publisher: Deutsche Grammophon
    :NDisks:    1
    :END:
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You may define the allowed values for a particular property &lt;code&gt;Xyz&lt;/code&gt; by setting a property &lt;code&gt;Xyz_ALL&lt;/code&gt;. This special property is inherited, so if you set it in a level 1 entry, it applies to the entire tree. When allowed values are defined, setting the corresponding property becomes easier and is less prone to typing errors. For the example with the CD collection, we can pre-define publishers and the number of disks in a box like this:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;* CD collection
  :PROPERTIES:
  :NDisks_ALL:  1 2 3 4
  :Publisher_ALL: &#34;Deutsche Grammophon&#34; Philips EMI
  :END:
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you want to set properties that can be inherited by any entry in a file, use a line like:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt; #+PROPERTY: NDisks_ALL 1 2 3 4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This can be interesting for example if you want to track when was a header created:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;*** Title of header
   :PROPERTIES:
   :CREATED: &amp;lt;2023-03-03 Fri 12:11&amp;gt;
   :END:
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#agenda-searches&#34;&gt;How to do Agenda searches.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;When using the search agenda view you can:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Search by TODO states with &lt;code&gt;/WAITING&lt;/code&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;Search by tags &lt;code&gt;+home&lt;/code&gt;. The syntax for such searches follows a simple boolean logic:&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;code&gt;|&lt;/code&gt;: or&lt;/p&gt; &lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;amp;&lt;/code&gt;: and&lt;/li&gt; &lt;li&gt;&lt;code&gt;+&lt;/code&gt;: include matches&lt;/li&gt; &lt;li&gt;&lt;code&gt;-&lt;/code&gt;: exclude matches&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Here are a few examples:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;+computer&amp;amp;+urgent&lt;/code&gt;: Returns all items tagged both &lt;code&gt;computer&lt;/code&gt; and &lt;code&gt;urgent&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;&lt;code&gt;+computer|+urgent&lt;/code&gt;: Returns all items tagged either &lt;code&gt;computer&lt;/code&gt; or &lt;code&gt;urgent&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;&lt;code&gt;+computer&amp;amp;-urgent&lt;/code&gt;: Returns all items tagged &lt;code&gt;computer&lt;/code&gt; and not &lt;code&gt;urgent&lt;/code&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;As you may have noticed, the syntax above can be a little verbose, so org-mode offers convenient ways of shortening it. First, &lt;code&gt;-&lt;/code&gt; and &lt;code&gt;+&lt;/code&gt; imply &lt;code&gt;and&lt;/code&gt; if no boolean operator is stated, so example three above could be rewritten simply as:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;+computer-urgent
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Second, inclusion of matches is implied if no &lt;code&gt;+&lt;/code&gt; or &lt;code&gt;-&lt;/code&gt; is present, so example three could be further shortened to:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;computer-urgent
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Example number two, meanwhile, could be shortened to:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;computer|urgent
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;There is no way (as yet) to express search grouping with parentheses. The &lt;code&gt;and&lt;/code&gt; operators (&lt;code&gt;&amp;amp;&lt;/code&gt;, &lt;code&gt;+&lt;/code&gt;, and &lt;code&gt;-&lt;/code&gt;) always bind terms together more strongly than &lt;code&gt;or&lt;/code&gt; (&lt;code&gt;|&lt;/code&gt;). For instance, the following search&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;computer|work+email
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Results in all headlines tagged either with &lt;code&gt;computer&lt;/code&gt; or both &lt;code&gt;work&lt;/code&gt; and &lt;code&gt;email&lt;/code&gt;. An expression such as &lt;code&gt;(computer|work)&amp;amp;email&lt;/code&gt; is not supported at the moment. You can construct a regular expression though:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;+{computer\|work}+email
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://orgmode.org/worg/org-tutorials/advanced-searching.html#property-searches&#34;&gt;Search by properties&lt;/a&gt;: You can search by properties with the &lt;code&gt;PROPERTY=&#34;value&#34;&lt;/code&gt; syntax. Properties with numeric values can be queried with inequalities &lt;code&gt;PAGES&amp;gt;100&lt;/code&gt;. To search by partial searches use a regular expression, for example if the entry had &lt;code&gt;:BIB_TITLE: Mysteries of the Amazon&lt;/code&gt; you could use &lt;code&gt;BIB_TITLE={Amazon}&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#capture&#34;&gt;How to use Capture in orgmode.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Capture lets you quickly store notes with little interruption of your work flow. It works the next way:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Open the interface with &lt;code&gt;;c&lt;/code&gt; (Default &lt;code&gt;&amp;lt;leader&amp;gt;oc&lt;/code&gt;) that asks you what kind of element you want to capture.&lt;/li&gt; &lt;li&gt;Select the template you want to use. By default you only have the &lt;code&gt;Task&lt;/code&gt; template, that introduces a task into the same file where you&#39;re at, select it by pressing &lt;code&gt;t&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;Fill up the template.&lt;/li&gt; &lt;li&gt;Choose what to do with the captured content:&lt;/li&gt; &lt;li&gt;Save it to the configured file by pressing &lt;code&gt;;w&lt;/code&gt; (Default &lt;code&gt;&amp;lt;control&amp;gt;c&lt;/code&gt;)&lt;/li&gt; &lt;li&gt;Refile it to a file by pressing &lt;code&gt;;r&lt;/code&gt; (Default &lt;code&gt;&amp;lt;leader&amp;gt;or&lt;/code&gt;).&lt;/li&gt; &lt;li&gt;Abort the capture &lt;code&gt;;q&lt;/code&gt; (Default &lt;code&gt;&amp;lt;leader&amp;gt;ok&lt;/code&gt;).&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;mappings&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;global&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;org_capture&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;;c&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;capture&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;org_capture_finalize&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;;w&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;org_capture_refile&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;;r&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;org_capture_kill&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;;q&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#configure-the-capture-templates&#34;&gt;Configure the capture templates.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Capture lets you define different templates for the different inputs. Each template has the next elements:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Keybinding: Keys to press to activate the template&lt;/li&gt; &lt;li&gt;Description: What to show in the capture menu to describe the template&lt;/li&gt; &lt;li&gt;Template: The actual template of the capture, look below to see how to create them.&lt;/li&gt; &lt;li&gt;Target: The place where the captured element will be inserted to. For example &lt;code&gt;~/org/todo.org&lt;/code&gt;. If you don&#39;t define it it will go to the file configured in &lt;code&gt;org_default_notes_file&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;Headline: An &lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/issues/196&#34;&gt;optional headline&lt;/a&gt; of the Target file to insert the element.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;org_capture_templates&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;t&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;description&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;Task&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;template&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;* TODO %?&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;  %u&#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;For the template you can use the next variables:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;%?:&lt;/code&gt;Default cursor position when template is opened&lt;/li&gt; &lt;li&gt;&lt;code&gt;%t&lt;/code&gt;: Prints current date (Example: &lt;code&gt;&amp;lt;2021-06-10 Thu&amp;gt;&lt;/code&gt;)&lt;/li&gt; &lt;li&gt;&lt;code&gt;%T&lt;/code&gt;: Prints current date and time (Example: &lt;code&gt;&amp;lt;2021-06-10 Thu 12:30&amp;gt;&lt;/code&gt;)&lt;/li&gt; &lt;li&gt;&lt;code&gt;%u&lt;/code&gt;: Prints current date in inactive format (Example: &lt;code&gt;[2021-06-10 Thu]&lt;/code&gt;)&lt;/li&gt; &lt;li&gt;&lt;code&gt;%U&lt;/code&gt;: Prints current date and time in inactive format (Example: &lt;code&gt;[2021-06-10 Thu 12:30]&lt;/code&gt;)&lt;/li&gt; &lt;li&gt;&lt;code&gt;%&amp;lt;FORMAT&amp;gt;&lt;/code&gt;: Insert current date/time formatted according to lua date format (Example: &lt;code&gt;%&amp;lt;%Y-%m-%d %A&amp;gt;&lt;/code&gt; produces &lt;code&gt;2021-07-02 Friday&lt;/code&gt;)&lt;/li&gt; &lt;li&gt;&lt;code&gt;%x&lt;/code&gt;: Insert content of the clipboard via the &#34;+&#34; register (see &lt;code&gt;:help clipboard&lt;/code&gt;)&lt;/li&gt; &lt;li&gt;&lt;code&gt;%^{PROMPT|DEFAULT|COMPLETION...}&lt;/code&gt;: Prompt for input, if completion is provided an &lt;code&gt;:h inputlist&lt;/code&gt; will be used&lt;/li&gt; &lt;li&gt;&lt;code&gt;%(EXP)&lt;/code&gt;: Runs the given lua code and inserts the result. NOTE: this will internally pass the content to the lua &lt;code&gt;load()&lt;/code&gt; function. So the body inside &lt;code&gt;%()&lt;/code&gt; should be the body of a function that returns a string.&lt;/li&gt; &lt;li&gt;&lt;code&gt;%f&lt;/code&gt;: Prints the file of the buffer capture was called from.&lt;/li&gt; &lt;li&gt;&lt;code&gt;%F&lt;/code&gt;: Like &lt;code&gt;%f&lt;/code&gt; but inserts the full path.&lt;/li&gt; &lt;li&gt;&lt;code&gt;%n&lt;/code&gt;: Inserts the current &lt;code&gt;$USER&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;%a&lt;/code&gt;: File and line number from where capture was initiated (Example: &lt;code&gt;[[file:/home/user/projects/myfile.txt +2]]&lt;/code&gt;)&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;description&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;Todo&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;template&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;* TODO %?&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt; %u&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;target&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;~/org/todo.org&#39;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
 &lt;span class=&#34;n&#34;&gt;j&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;description&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;Journal&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;template&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;*** %&amp;lt;%Y-%m-%d %A&amp;gt;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;**** %U&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n\n&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;%?&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;target&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;~/sync/org/journal.org&#39;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;-- Nested key example:&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;  &lt;span class=&#34;s1&#34;&gt;&#39;Event&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;er&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;description&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;recurring&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;template&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;** %?&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt; %T&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;target&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;~/org/calendar.org&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;headline&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;recurring&#39;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;eo&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;description&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;one-time&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;template&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;** %?&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt; %T&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;target&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;~/org/calendar.org&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;headline&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;one-time&#39;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;-- Example using a lua function&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;r&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;description&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Repo URL&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;template&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;* [[%x][%(return string.match(&#39;%x&#39;, &#39;([^/]+)$&#39;))]]%?&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;target&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;~/org/repos.org&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#synchronize-with-external-calendars&#34;&gt;Synchronize with external calendars.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You may want to synchronize your calendar entries with external ones shared with other people, such as nextcloud calendar or google.&lt;/p&gt; &lt;p&gt;The orgmode docs have a tutorial to &lt;a href=&#34;https://orgmode.org/worg/org-tutorials/org-google-sync.html&#34;&gt;sync with google&lt;/a&gt; and suggests some orgmode packages that do that, sadly it won&#39;t work with &lt;code&gt;nvim-orgmode&lt;/code&gt;. We&#39;ll need to go the &#34;ugly way&#34; by:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Downloading external calendar events to ics with &lt;a href=&#34;https://lyz-code.github.io/blue-book/vdirsyncer/&#34;&gt;&lt;code&gt;vdirsyncer&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#importing-the-ics-to-orgmode&#34;&gt;Importing the ics to orgmode&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Editing the events in orgmode&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#exporting-from-orgmode-to-ics&#34;&gt;Exporting from orgmode to ics&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Uploading then changes to the external calendar events with &lt;a href=&#34;https://lyz-code.github.io/blue-book/vdirsyncer/&#34;&gt;&lt;code&gt;vdirsyncer&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#comparison-with-markdown&#34;&gt;Comparison with Markdown.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;What I like of Org mode over Markdown:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The whole interface to interact with the elements of the document through key bindings:&lt;/li&gt; &lt;li&gt;Move elements around.&lt;/li&gt; &lt;li&gt;Create elements&lt;/li&gt; &lt;li&gt;The TODO system is awesome&lt;/li&gt; &lt;li&gt;The Agenda system&lt;/li&gt; &lt;li&gt;How it handles checkboxes &amp;lt;3&lt;/li&gt; &lt;li&gt;Easy navigation between references in the document&lt;/li&gt; &lt;li&gt;Archiving feature&lt;/li&gt; &lt;li&gt;Refiling feature&lt;/li&gt; &lt;li&gt;&lt;code&gt;#&lt;/code&gt; is used for comments.&lt;/li&gt; &lt;li&gt;Create internal document links is easier, you can just copy and paste the heading similar to &lt;code&gt;[[*This is the heading]]&lt;/code&gt; on markdown you need to edit it to &lt;code&gt;[](#this-is-the-heading)&lt;/code&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;What I like of markdown over Org mode:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The syntax of the headings &lt;code&gt;## Title&lt;/code&gt; better than &lt;code&gt;** Title&lt;/code&gt;. Although it makes sense to have &lt;code&gt;#&lt;/code&gt; for comments.&lt;/li&gt; &lt;li&gt;The syntax of the links: &lt;code&gt;[reference](link)&lt;/code&gt; is prettier to read and write than &lt;code&gt;[[link][reference]]&lt;/code&gt;, although this can be improved if only the reference is shown by your editor (nvim-orgmode doesn&#39;t do his yet)&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Note the importance of isolated containers.&lt;/p&gt; &lt;p&gt;It&#39;s critical that all of these containers be kept distinct from one another. They each represent a discrete type of agreement we make with ourselves, to be reminded of at a specific time and in a specific way, and if they lose their edges and begin to blend, much of the value of organizing will be lost. That&#39;s why capturing and clarifying what your relationship to them is primary to getting organized.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#inbox-management&#34;&gt;Inbox management.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Inbox is the container where you &lt;a href=&#34;#capture&#34;&gt;capture your stuff&lt;/a&gt;. I&#39;ve found myself capturing stuff in each of my devices: computer, mobile phone and tablet. Each of them has their own org file under the &lt;code&gt;inbox&lt;/code&gt; directory. Each of these files has the &lt;code&gt;#+FILETAGS: :inbox:&lt;/code&gt; heading so that all elements share the tag.&lt;/p&gt; &lt;p&gt;Part of the daily planning is to check the computer and mobile inboxes to see if there is anything that needs to be processed on the day. I don&#39;t check the tablet inbox as there&#39;s usually no urgent stuff there. The rest of the elements will be processed on the weekly review leaving all the inbox files empty.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#computer-inbox-management&#34;&gt;Computer inbox management.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/&#34;&gt;&lt;code&gt;nvim-orgmode&lt;/code&gt;&lt;/a&gt; has an awesome feature called &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#capture&#34;&gt;capture&lt;/a&gt; which lets you capture thoughts with a keystroke. This is awesome as no matter what are you doing inside &lt;code&gt;neovim&lt;/code&gt; you can quickly record your thought, action or idea and keep on doing whatever you were doing. It&#39;s a very efficient way to record your &lt;em&gt;stuff&lt;/em&gt; at the same time as you keep your focus.&lt;/p&gt; &lt;p&gt;You can use the next capture template:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;  &lt;span class=&#34;n&#34;&gt;org_capture_templates&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;description&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Inbox&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;template&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;* TODO %?&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; %U&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;target&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;~/org/inbox/computer.org&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#mobile-and-tablet-inbox-management&#34;&gt;Mobile and tablet inbox management.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To capture the content on the go you can use the &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgzly/&#34;&gt;orgzly&lt;/a&gt; and then sync them with your computer through &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/syncthing/&#34;&gt;syncthing&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#calendar-management&#34;&gt;Calendar management.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You need to trust your calendar as sacred territory, reflecting the exact hard edges of your day&#39;s commitments, which should be noticeable at a glance while you&#39;re on the run.&lt;/p&gt; &lt;p&gt;So for each element you encounter in the calendar ask yourself, does this element &lt;strong&gt;need&lt;/strong&gt; to be done on this hard date? If the answer is no, then the calendar is not the correct place for the element to be.&lt;/p&gt; &lt;p&gt;Using dates to order your tasks it&#39;s a waste of time, because there will always be a thousand of reasons why you can&#39;t do all the things you allocate to that day. As these not done issues start piling up, you&#39;ll start to get stressed with a lot of things that you were not able to do on the dates you deceived yourself you were supposed to do at and then you need to spend time defining a new date. Use next actions in your &lt;code&gt;todo&lt;/code&gt; instead.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#priority-management&#34;&gt;Priority management.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You shouldn’t bother to create some external structuring of the priorities on your lists that you’ll then have to rearrange or rewrite as things change. Attempting to impose such scaffolding has been a big source of frustration in many people’s organizing. You’ll be prioritizing more intuitively as you see the whole list against quite a number of shifting variables. The list is just a way for you to keep track of the total inventory of active things to which you have made a commitment, and to have that inventory available for review.&lt;/p&gt; &lt;p&gt;Therefore I&#39;m going to try not to use orgmode&#39;s priorities for the tasks.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#soft-recurrent-tasks&#34;&gt;Soft recurrent tasks.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;There are some tasks that have a soft recurrence meaning that once you do them you don&#39;t want them to show up in your list of actions until a specific time has passed. You could use a recurrent &lt;code&gt;DEADLINE&lt;/code&gt; or &lt;code&gt;SCHEDULED&lt;/code&gt; but as we&#39;ve seen earlier that will clutter your calendar pretty soon. Try following the next workflow with these tasks:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Add the &lt;code&gt;:soft_recurrence:&lt;/code&gt; tag to keep them tracked.&lt;/li&gt; &lt;li&gt;Add them to the tickler file with a recurrent appointment date &lt;code&gt;&amp;lt;2023-03-13 Mon ++1w&amp;gt;&lt;/code&gt; and the &lt;code&gt;:tickler:&lt;/code&gt; tag so that it doesn&#39;t show up in the agenda view even if you move it to another file.&lt;/li&gt; &lt;li&gt;When the appointed day comes you&#39;ll review the tickler elements as part of your day&#39;s routine. If you think it&#39;s time to do it, refile it to the &lt;code&gt;todo.org&lt;/code&gt; file, if not, adjust the recurrence period and set the next date. Even though this workflow is reproducing the &#34;kick the can forward&#34; that we want to avoid, the idea is that once you get the period right you&#39;ll never have to do it again. If you see that after some iterations the period keeps on changing, maybe this workflow is not working for that kind of task and you may need to think of a better system &lt;code&gt;¯\(°_o)/¯&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;Once you complete the item, the new one will be spawned, once it has refile it to the tickler file again.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;We use appointments instead of &lt;code&gt;DEADLINE&lt;/code&gt; or &lt;code&gt;SCHEDULED&lt;/code&gt; so that they don&#39;t clutter the tickler view if you don&#39;t do them on the appointment date.&lt;/p&gt; &lt;p&gt;Another option is not to archive the DONE tasks and in the weekly reset them to TODO the ones that you want to do the next week.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#create-an-issue-in-the-orgmode-repository&#34;&gt;Create an issue in the orgmode repository.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Refile from the capture window.&lt;/p&gt; &lt;p&gt;If you refile from the capture window, &lt;a href=&#34;https://github.com/joaomsa/telescope-orgmode.nvim/issues/4&#34;&gt;until this issue is solved&lt;/a&gt;, your task will be refiled but the capture window won&#39;t be closed.&lt;/p&gt; &lt;p&gt;Be careful that it only refiles the first task there is, so you need to close the capture before refiling the next&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#code-blocks&#34;&gt;Code blocks syntax.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Org offers two ways to structure source code in Org documents: in a source code block, and directly inline. Both specifications are shown below.&lt;/p&gt; &lt;p&gt;A source code block conforms to this structure:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;  &amp;lt;body&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You need to use snippets for this to be usable.&lt;/p&gt; &lt;p&gt;An inline code block conforms to this structure:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;src_&amp;lt;language&amp;gt;{&amp;lt;body&amp;gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;or&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;src_&amp;lt;language&amp;gt;[&amp;lt;header arguments&amp;gt;]{&amp;lt;body&amp;gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;#+NAME: &amp;lt;name&amp;gt;&lt;/code&gt;: (Optional) Names the source block so it can be called, like a function, from other source blocks or inline code to evaluate or to capture the results. Code from other blocks, other files.&lt;/li&gt; &lt;li&gt;&lt;code&gt;#+BEGIN_SRC’ … ‘#+END_SRC&lt;/code&gt;: (Mandatory) They mark the start and end of a block that Org requires.&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;language&amp;gt;&lt;/code&gt;: (Mandatory) It is the identifier of the source code language in the block. See &lt;a href=&#34;https://orgmode.org/worg/org-contrib/babel/languages/index.html&#34;&gt;Languages&lt;/a&gt; for identifiers of supported languages.&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;switches&amp;gt;&lt;/code&gt;: (Optional) Switches provide finer control of the code execution, export, and format.&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;header arguments&amp;gt;&lt;/code&gt;: (Optional) Heading arguments control many aspects of evaluation, export and tangling of code blocks. Using Org’s properties feature, header arguments can be selectively applied to the entire buffer or specific subtrees of the Org document.&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt;: Source code in the dialect of the specified language identifier.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#narrow/widen-to-subtree&#34;&gt;Narrow/Widen to subtree.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It&#39;s &lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/issues/200&#34;&gt;not yet supported&lt;/a&gt; to focus or zoom on one task.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#interesting-things-to-investigate&#34;&gt;Interesting things to investigate.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/akinsho/org-bullets.nvim&#34;&gt;org-bullets.nvim&lt;/a&gt;: Show org mode bullets as UTF-8 characters.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/lukas-reineke/headlines.nvim&#34;&gt;headlines.nvim&lt;/a&gt;: Add few highlight options for code blocks and headlines.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/michaelb/sniprun&#34;&gt;Sniprun&lt;/a&gt;: A neovim plugin to run lines/blocs of code (independently of the rest of the file), supporting multiples languages.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/kenkeiras/org-rw&#34;&gt;Python library: Org-rw&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/topics/orgmode-nvim&#34;&gt;List of plugins&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#the-orgmode-repository-file-organization&#34;&gt;The orgmode repository file organization.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;How to structure the different orgmode files is something that has always confused me, each one does it&#39;s own way, and there are no good posts on why one structure is better than other, people just state what they do.&lt;/p&gt; &lt;p&gt;I&#39;ve started with a typical &lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/&#34;&gt;gtd&lt;/a&gt; structure with a directory for the &lt;code&gt;todo&lt;/code&gt; another for the &lt;code&gt;calendar&lt;/code&gt; then another for the &lt;code&gt;references&lt;/code&gt;. In the &lt;code&gt;todo&lt;/code&gt; I had a file for personal stuff, another for each of my work clients, and the &lt;code&gt;someday.org&lt;/code&gt;. Soon making the internal links was cumbersome so I decided to merge the personal &lt;code&gt;todo.org&lt;/code&gt; and the &lt;code&gt;someday.org&lt;/code&gt; into the same file and use folds to hide uninteresting parts of the file. The reality is that I feel that orgmode is less responsive and that I often feel lost in the file.&lt;/p&gt; &lt;p&gt;I&#39;m now more into the idea of having files per project in a flat structure and use an index.org file to give it some sense in the same way I do with the mkdocs repositories. Then I&#39;d use internal links in the todo.org file to organize the priorities of what to do next.&lt;/p&gt; &lt;p&gt;Benefits:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;As we&#39;re using a flat structure at file level, the links between the files are less cumbersome &lt;code&gt;file:./project.org::*heading&lt;/code&gt;. We only need to have unique easy to remember names for the files, instead of having to think on which directory was the file I want to make the link to. The all in one file structure makes links even easier, just &lt;code&gt;*heading&lt;/code&gt;, but the disadvantages make it not worth it.&lt;/li&gt; &lt;li&gt;You have the liberty to have a generic link like &lt;code&gt;Work on project&lt;/code&gt; or if you want to fine grain it, link the specific task of the project&lt;/li&gt; &lt;li&gt;The todo file will get smaller.&lt;/li&gt; &lt;li&gt;It has been the natural evolution of other knowledge repositories such as blue&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Cons:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Filenames must be unique. It hasn&#39;t been a problem in blue.&lt;/li&gt; &lt;li&gt;Blue won&#39;t be flattened into Vida as it&#39;s it&#39;s own knowledge repository&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#synchronizations&#34;&gt;Syncronize orgmode repositories.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I use orgmode both at the laptop and the mobile, I want to syncronize some files between both with the next requisites:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The files should be available on the devices when I&#39;m not at home&lt;/li&gt; &lt;li&gt;The synchronization will be done only on the local network&lt;/li&gt; &lt;li&gt;The synchronization mechanism will only be able to see the files that need to be synched.&lt;/li&gt; &lt;li&gt;Different files can be synced to different devices. If I have three devices (laptop, mobile, tablet) I want to sync all mobile files to the laptop but just some to the tablet).&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Right now I&#39;m already using &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/syncthing/&#34;&gt;syncthing&lt;/a&gt; to sync files between the mobile and my server, so it&#39;s tempting to use it also to solve this issue. So the first approach is to spawn a syncthing docker at the laptop that connects with the server to sync the files whenever I&#39;m at home.&lt;/p&gt; &lt;p&gt;I&#39;ve investigated the next options:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#mount-the-whole-orgmode-repository-with-syncthing&#34;&gt;Mount the whole orgmode repository with syncthing&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#mount-a-specific-directory-to-sync&#34;&gt;Mount a specific directory to sync&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#use-the-org-orgzly-script&#34;&gt;Use the org-orgzly script&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;openproject&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/openproject/&#34;&gt;OpenProject&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Suggest not to use openproject.&lt;/p&gt; &lt;p&gt;I&#39;ve decided to use &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/&#34;&gt;orgmode&lt;/a&gt; instead.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;knowledge-management&#34;&gt;Knowledge Management&lt;/h3&gt; &lt;h4 id=&#34;spaced-repetition&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/spaced_repetition/&#34;&gt;Spaced Repetition&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce spaced repetition references.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://collegeinfogeek.com/spaced-repetition-memory-technique/&#34;&gt;https://collegeinfogeek.com/spaced-repetition-memory-technique/&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=uvF1XuseZFE&#34;&gt;The leitner box&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;anki&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/anki/&#34;&gt;Anki&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: How to install the latest version.&lt;/p&gt; &lt;p&gt;Install the dependencies:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zstd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Download &lt;a href=&#34;https://apps.ankiweb.net/&#34;&gt;the latest release package&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Open a terminal and run the following commands, replacing the filename as appropriate:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;tar&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;xaf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Downloads/anki-2.1.XX-linux-qt6.tar.zst
&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;anki-2.1.XX-linux-qt6
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;./install.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/anki/#how-long-to-do-study-sessions&#34;&gt;How long to do study sessions.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I have two study modes:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;When I&#39;m up to date with my cards, I study them until I finish, but usually less than 15 minutes.&lt;/li&gt; &lt;li&gt;If I have been lazy and haven&#39;t checked them in a while (like now) I assume I&#39;m not going to see them all and define a limited amount of time to review them, say 10 to 20 minutes depending on the time/energy I have at the moment.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The relief thought you can have is that as long as you keep a steady pace of 10/20 mins each day, inevitably you&#39;ll eventually finish your pending cards as you&#39;re more effective reviewing cards than entering new ones&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#39;../../anki/#what-to-do-with-&#34;hard&#34;-cards&#39;&gt;What to do with &#34;hard&#34; cards.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you&#39;re afraid to be stuck in a loop of reviewing &#34;hard&#34; cards, don&#39;t be. In reality after you&#39;ve seen that &#34;hard&#34; card three times in a row you won&#39;t mark it as hard again, because you will remember. If you don&#39;t maybe there are two reasons:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The card has too much information that should be subdivided in smaller cards.&lt;/li&gt; &lt;li&gt;You&#39;re not doing a good process of memorizing the contents once they show up.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/anki/#what-to-do-with-unneeded-cards&#34;&gt;What to do with unneeded cards.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You have three options:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Suspend: It stops it from showing up permanently until you reactivate it through the browser.&lt;/li&gt; &lt;li&gt;Bury: Just delays it until the next day.&lt;/li&gt; &lt;li&gt;Delete: It deletes it forever.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Unless you&#39;re certain that you are not longer going to need it, suspend it.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/anki/#configure-self-hosted-synchronization&#34;&gt;Configure self hosted synchronization.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Explain how to install &lt;code&gt;anki-sync-server&lt;/code&gt; and how to configure Ankidroid and Anki. In the end I dropped this path and used Ankidroid alone with syncthing as I didn&#39;t need to interact with the decks from the computer. Also the ecosystem of synchronization in Anki at 2023-11-10 is confusing as there are many servers available, not all are compatible with the clients and Anki itself has released it&#39;s own so some of the community ones will eventually die.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;computer-configuration-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/configuration_management/&#34;&gt;Computer configuration management&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce configuration management.&lt;/p&gt; &lt;p&gt;Configuring your devices is boring, disgusting and complex. Specially when your device dies and you need to reinstall. You usually don&#39;t have the time or energy to deal with it, you just want it to work.&lt;/p&gt; &lt;p&gt;To have a system that allows you to recover from a disaster it&#39;s expensive in both time and knowledge, and many people have different solutions.&lt;/p&gt; &lt;p&gt;This article shows the latest step of how I&#39;m doing it.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;game-theory&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/game_theory/&#34;&gt;Game Theory&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add the evolution of trust game theory game.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://ncase.me/trust/&#34;&gt;Evolution of trust&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Game theory shows us the three things we need for the evolution of trust:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Repeat interactions: Trust keeps a relationship going, but you need the knowledge of possible future repeat interactions before trust can evolve&lt;/li&gt; &lt;li&gt;Possible win-wins: You must be playing a non-zero-sum game, a game where it&#39;s at least possible that both players can be better off -- a win-win.&lt;/li&gt; &lt;li&gt;Low miscommunication: If the level of miscommunication is too high, trust breaks down. But when there&#39;s a little bit of miscommunication, it pays to be more forgiving&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;coding&#34;&gt;Coding&lt;/h2&gt; &lt;h3 id=&#34;languages&#34;&gt;Languages&lt;/h3&gt; &lt;h4 id=&#34;bash-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/python/&#34;&gt;Bash snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/python/#move-a-file&#34;&gt;Move a file.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use one of the following&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;shutil&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;path/to/current/file.foo&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;path/to/new/destination/for/file.foo&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;replace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;path/to/current/file.foo&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;path/to/new/destination/for/file.foo&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;shutil&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;move&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;path/to/current/file.foo&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;path/to/new/destination/for/file.foo&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/#get-the-root-path-of-a-git-repository&#34;&gt;Get the root path of a git repository.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rev-parse&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--show-toplevel
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/#get-epoch-gmt-time&#34;&gt;Get epoch gmt time.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;date&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-u&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;+%s&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/#check-the-length-of-an-array-with-jq&#34;&gt;Check the length of an array with jq.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;echo &#39;[{&#34;username&#34;:&#34;user1&#34;},{&#34;username&#34;:&#34;user2&#34;}]&#39; | jq &#39;. | length&#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/#exit-the-script-if-there-is-an-error&#34;&gt;Exit the script if there is an error.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-eu
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/#prompt-the-user-for-data&#34;&gt;Prompt the user for data.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Ask whatever&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;choice
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/#how-to-deal-with-hostcontextswitching-alertmanager-alert&#34;&gt;How to deal with HostContextSwitching alertmanager alert.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;A context switch is described as the kernel suspending execution of one process on the CPU and resuming execution of some other process that had previously been suspended. A context switch is required for every interrupt and every task that the scheduler picks.&lt;/p&gt; &lt;p&gt;Context switching can be due to multitasking, Interrupt handling , user &amp;amp; kernel mode switching. The interrupt rate will naturally go high, if there is higher network traffic, or higher disk traffic. Also it is dependent on the application which every now and then invoking system calls.&lt;/p&gt; &lt;p&gt;If the cores/CPU&#39;s are not sufficient to handle load of threads created by application will also result in context switching.&lt;/p&gt; &lt;p&gt;It is not a cause of concern until performance breaks down. This is expected that CPU will do context switching. One shouldn&#39;t verify these data at first place since there are many statistical data which should be analyzed prior to looking into kernel activities. Verify the CPU, memory and network usage during this time.&lt;/p&gt; &lt;p&gt;You can see which process is causing issue with the next command:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:24&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;UID&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;PID&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;cswch/s&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;nvcswch/s&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;Command
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;162656&lt;/span&gt;.7&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;16656&lt;/span&gt;.7&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;systemd
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;9&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;165451&lt;/span&gt;.04&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;15451&lt;/span&gt;.04&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;ksoftirqd/0
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;158628&lt;/span&gt;.87&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;15828&lt;/span&gt;.87&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;rcu_sched
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;156147&lt;/span&gt;.47&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;15647&lt;/span&gt;.47&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;migration/0
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;17&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;150135&lt;/span&gt;.71&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;15035&lt;/span&gt;.71&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;ksoftirqd/1
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;23&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;129769&lt;/span&gt;.61&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;12979&lt;/span&gt;.61&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;ksoftirqd/2
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;29&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2238&lt;/span&gt;.38&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;238&lt;/span&gt;.38&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;ksoftirqd/3
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;43&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1753&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;753&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;khugepaged
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;443&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1659&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;165&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;usb-storage
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;456&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1956&lt;/span&gt;.12&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;156&lt;/span&gt;.12&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;i915/signal:0
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;465&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;29550&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;29550&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;kworker/3:1H-xfs-log/dm-3
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;490&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;164700&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;14700&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;kworker/0:1H-kblockd
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;506&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;163741&lt;/span&gt;.24&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;16741&lt;/span&gt;.24&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;kworker/1:1H-xfs-log/dm-3
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;594&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;154742&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;154742&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;dmcrypt_write/2
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;629&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;162021&lt;/span&gt;.65&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;16021&lt;/span&gt;.65&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;kworker/2:1H-kblockd
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;715&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;147852&lt;/span&gt;.48&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;14852&lt;/span&gt;.48&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;xfsaild/dm-1
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;886&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;150706&lt;/span&gt;.86&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;15706&lt;/span&gt;.86&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;irq/131-iwlwifi
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;966&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;135597&lt;/span&gt;.92&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;13597&lt;/span&gt;.92&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;xfsaild/dm-3
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;81&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1037&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2325&lt;/span&gt;.25&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;225&lt;/span&gt;.25&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;dbus-daemon
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;998&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1052&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;118755&lt;/span&gt;.1&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11755&lt;/span&gt;.1&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;polkitd
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;70&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1056&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;158248&lt;/span&gt;.51&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;15848&lt;/span&gt;.51&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;avahi-daemon
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1061&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;133512&lt;/span&gt;.12&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;455&lt;/span&gt;.12&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;rngd
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1110&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;156230&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;16230&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;cupsd
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1192&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;152298&lt;/span&gt;.02&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1598&lt;/span&gt;.02&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;sssd_nss
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1247&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;166132&lt;/span&gt;.99&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;16632&lt;/span&gt;.99&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;systemd-logind
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1265&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;165311&lt;/span&gt;.34&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;16511&lt;/span&gt;.34&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;cups-browsed
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1408&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10556&lt;/span&gt;.57&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1556&lt;/span&gt;.57&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;wpa_supplicant
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1687&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3835&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3835&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;splunkd
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;42&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1773&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3728&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3728&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;Xorg
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;42&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1996&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3266&lt;/span&gt;.67&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;266&lt;/span&gt;.67&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;gsd-color
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3166&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;32036&lt;/span&gt;.36&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3036&lt;/span&gt;.36&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;sssd_kcm
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;119349&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3194&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;151763&lt;/span&gt;.64&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11763&lt;/span&gt;.64&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;dbus-daemon
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;119349&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3199&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;158306&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;18306&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;Xorg
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:27&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;119349&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3242&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;15&lt;/span&gt;.28&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;5&lt;/span&gt;.8&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;gnome-shell

pidstat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-wt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/tmp/pidstat-t.out

Linux&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4&lt;/span&gt;.18.0-80.11.2.el8_0.x86_64&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;hostname&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;09&lt;/span&gt;/08/2020&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;_x86_64_&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;CPU&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:15&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;UID&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;TGID&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;TID&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;cswch/s&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;nvcswch/s&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Command
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;152656&lt;/span&gt;.7&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;16656&lt;/span&gt;.7&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;systemd
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;152656&lt;/span&gt;.7&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;16656&lt;/span&gt;.7&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;__systemd
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;9&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;165451&lt;/span&gt;.04&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;15451&lt;/span&gt;.04&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;ksoftirqd/0
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;9&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;165451&lt;/span&gt;.04&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;15451&lt;/span&gt;.04&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;__ksoftirqd/0
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;158628&lt;/span&gt;.87&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;15828&lt;/span&gt;.87&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;rcu_sched
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;158628&lt;/span&gt;.87&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;15828&lt;/span&gt;.87&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;__rcu_sched
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;23&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;129769&lt;/span&gt;.61&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;12979&lt;/span&gt;.61&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;ksoftirqd/2
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;23&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;129769&lt;/span&gt;.61&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;12979&lt;/span&gt;.33&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;__ksoftirqd/2
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;29&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;32424&lt;/span&gt;.5&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2445&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;ksoftirqd/3
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;29&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;32424&lt;/span&gt;.5&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2445&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;__ksoftirqd/3
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;43&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;334&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;34&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;khugepaged
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;43&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;334&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;34&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;__khugepaged
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;443&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11465&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;566&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;usb-storage
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;443&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;6433&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;93&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;__usb-storage
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;456&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;15&lt;/span&gt;.41&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.00&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;i915/signal:0
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;456&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;15&lt;/span&gt;.41&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.00&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;__i915/signal:0
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;715&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;19&lt;/span&gt;.34&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.00&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;xfsaild/dm-1
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;715&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;19&lt;/span&gt;.34&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.00&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;__xfsaild/dm-1
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;886&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;23&lt;/span&gt;.28&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.00&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;irq/131-iwlwifi
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;886&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;23&lt;/span&gt;.28&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.00&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;__irq/131-iwlwifi
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;966&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;19&lt;/span&gt;.67&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.00&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;xfsaild/dm-3
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;966&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;19&lt;/span&gt;.67&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.00&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;__xfsaild/dm-3
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;81&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1037&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;6&lt;/span&gt;.89&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.33&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;dbus-daemon
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;81&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1037&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;6&lt;/span&gt;.89&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.33&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;__dbus-daemon
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1038&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11567&lt;/span&gt;.31&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4436&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;NetworkManager
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1038&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;.31&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.00&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;__NetworkManager
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1088&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.33&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.00&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;__gmain
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1094&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1340&lt;/span&gt;.66&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.00&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;__gdbus
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;998&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1052&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;118755&lt;/span&gt;.1&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11755&lt;/span&gt;.1&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;polkitd
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;998&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1052&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;32420&lt;/span&gt;.66&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;25545&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;__polkitd
&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;:15:19&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;AM&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;998&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1132&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.66&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.00&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;__gdbus
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then with help of PID which is causing issue, one can get all system calls details: Raw&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Let this command run for a few minutes while the load/context switch rates are high. It is safe to run this on a production system so you could run it on a good system as well to provide a comparative baseline. Through strace, one can debug &amp;amp; troubleshoot the issue, by looking at system calls the process has made.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/#redirect-stderr-of-all-subsequent-commands-of-a-script-to-a-file&#34;&gt;Redirect stderr of all subsequent commands of a script to a file.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;somecommand
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;somecommand2
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;somecommand3
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;&lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tee&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$DEBUGLOG&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/#loop-through-a-list-of-files-found-by-find&#34;&gt;Loop through a list of files found by find.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;For simple loops use the &lt;code&gt;find -exec&lt;/code&gt; syntax:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;find&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;*.txt&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-exec&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;process&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;For more complex loops use a &lt;code&gt;while read&lt;/code&gt; construct:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;find&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;*.txt&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-print0&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;$&#39;\0&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;file
&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;…code&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;using&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$file&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The loop will execute while the &lt;code&gt;find&lt;/code&gt; command is executing. Plus, this command will work even if a file name is returned with whitespace in it. And, you won&#39;t overflow your command line buffer.&lt;/p&gt; &lt;p&gt;The &lt;code&gt;-print0&lt;/code&gt; will use the NULL as a file separator instead of a newline and the &lt;code&gt;-d $&#39;\0&#39;&lt;/code&gt; will use NULL as the separator while reading.&lt;/p&gt; &lt;p&gt;How not to do it:&lt;/p&gt; &lt;p&gt;If you try to run the next snippet:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;file&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;find&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;*.txt&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;…code&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;using&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$file&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You&#39;ll get the next &lt;a href=&#34;https://lyz-code.github.io/blue-book/shellcheck/&#34;&gt;&lt;code&gt;shellcheck&lt;/code&gt;&lt;/a&gt; warning:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;SC2044: For loops over find output are fragile. Use find -exec or a while read loop.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You should not do this because:&lt;/p&gt; &lt;p&gt;Three reasons:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;For the for loop to even start, the find must run to completion.&lt;/li&gt; &lt;li&gt;If a file name has any whitespace (including space, tab or newline) in it, it will be treated as two separate names.&lt;/li&gt; &lt;li&gt;Although now unlikely, you can overrun your command line buffer. Imagine if your command line buffer holds 32KB, and your for loop returns 40KB of text. That last 8KB will be dropped right off your for loop and you&#39;ll never know it.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pytelegrambotapi&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/pdm/&#34;&gt;pytelegrambotapi&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/pdm/#custom-file-generation&#34;&gt;Custom file generation.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;During the build, you may want to generate other files or download resources from the internet. You can achieve this by the setup-script build configuration:&lt;/p&gt; &lt;p&gt;&lt;code&gt;``toml&lt;/code&gt; [tool.pdm.build] setup-script = &#34;build.py&#34; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;In the `build.py` script, pdm-pep517 looks for a build function and calls it with two arguments:

* `src`: the path to the source directory
* `dst`: the path to the distribution directory

Example:

```python
def build(src, dst):
    target_file = os.path.join(dst, &#34;mypackage/myfile.txt&#34;)
    os.makedirs(os.path.dirname(target_file), exist_ok=True)
    download_file_to(dst)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;The generated file will be copied to the resulted wheel with the same hierarchy, you need to create the parent directories if necessary.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/pdm/#custom-file-generation&#34;&gt;Custom file generation.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Warning: this method only works if you install the package with &lt;code&gt;pdm&lt;/code&gt; if you use &lt;code&gt;pip&lt;/code&gt; or any other package manager the &lt;code&gt;build.py&lt;/code&gt; script won&#39;t be called. Thus a more generic approach is to run the initialization steps in a &lt;code&gt;your_command init&lt;/code&gt; step or run the checks on each command.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/asyncio/#concurrency&#34;&gt;Basic concepts of concurrency.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Concurrency is best explained by an example stolen from &lt;a href=&#34;https://youtu.be/iG6fr81xHKA?t=4m29s&#34;&gt;Miguel Grinberg&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Chess master Judit Polgár hosts a chess exhibition in which she plays multiple amateur players. She has two ways of conducting the exhibition: synchronously and asynchronously.&lt;/p&gt; &lt;p&gt;Assumptions:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;24 opponents&lt;/li&gt; &lt;li&gt;Judit makes each chess move in 5 seconds&lt;/li&gt; &lt;li&gt;Opponents each take 55 seconds to make a move&lt;/li&gt; &lt;li&gt;Games average 30 pair-moves (60 moves total)&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Synchronous version: Judit plays one game at a time, never two at the same time, until the game is complete. Each game takes (55 + 5) * 30 == 1800 seconds, or 30 minutes. The entire exhibition takes 24 * 30 == 720 minutes, or 12 hours.&lt;/p&gt; &lt;p&gt;Asynchronous version: Judit moves from table to table, making one move at each table. She leaves the table and lets the opponent make their next move during the wait time. One move on all 24 games takes Judit 24 * 5 == 120 seconds, or 2 minutes. The entire exhibition is now cut down to 120 * 30 == 3600 seconds, or just 1 hour.&lt;/p&gt; &lt;p&gt;Async IO takes long waiting periods in which functions would otherwise be blocking and allows other functions to run during that downtime. (A function that blocks effectively forbids others from running from the time that it starts until the time that it returns.)&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Basic concepts.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/asyncio/#asyncIO-is-not-easy&#34;&gt;AsyncIO is not easy&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/asyncio/#the-async-await-syntax-and-Native-coroutines&#34;&gt;The async/await Syntax and Native Coroutines&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/asyncio/#the-rules-of-async-io&#34;&gt;The Rules of Async IO&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/asyncio/#async-io-design-patterns&#34;&gt;Async IO Design Patterns&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/asyncio/#chaining-coroutines&#34;&gt;Chaining Coroutines&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/asyncio/#using-a-queue&#34;&gt;Using a Queue&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/asyncio/#async-for-and-list-comprehensions&#34;&gt;&lt;code&gt;async for&lt;/code&gt; and list comprehensions&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/asyncio/#creating-and-gathering-tasks&#34;&gt;Creating and gathering tasks&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/asyncio/#when-and-why-is-async-io-the-right-choice&#34;&gt;When and Why Is Async IO the Right Choice?&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/asyncio/#async-io-it-is-but-which-one&#34;&gt;Async IO It Is, but Which One?&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/asyncio/#testing&#34;&gt;Testing&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce pytelegrambotapi.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/eternnoir/pyTelegramBotAPI&#34;&gt;pyTelegramBotAPI&lt;/a&gt; is an synchronous and asynchronous implementation of the &lt;a href=&#34;https://core.telegram.org/bots/api&#34;&gt;Telegram Bot API&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://pytba.readthedocs.io/en/latest/install.html&#34;&gt;Installation&lt;/a&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pyTelegramBotAPI
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/pytelegrambotapi/#create-your-bot&#34;&gt;Create your bot.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use the &lt;code&gt;/newbot&lt;/code&gt; command to create a new bot. &lt;code&gt;@BotFather&lt;/code&gt; will ask you for a name and username, then generate an authentication token for your new bot.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The &lt;code&gt;name&lt;/code&gt; of your bot is displayed in contact details and elsewhere.&lt;/li&gt; &lt;li&gt;The &lt;code&gt;username&lt;/code&gt; is a short name, used in search, mentions and t.me links. Usernames are 5-32 characters long and not case sensitive – but may only include Latin characters, numbers, and underscores. Your bot&#39;s username must end in &#39;bot’, like &lt;code&gt;tetris_bot&lt;/code&gt; or &lt;code&gt;TetrisBot&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;The &lt;code&gt;token&lt;/code&gt; is a string, like &lt;code&gt;110201543:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw&lt;/code&gt;, which is required to authorize the bot and send requests to the Bot API. Keep your token secure and store it safely, it can be used by anyone to control your bot.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;To edit your bot, you have the next available commands:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;/setname&lt;/code&gt;: change your bot&#39;s name.&lt;/li&gt; &lt;li&gt;&lt;code&gt;/setdescription&lt;/code&gt;: change the bot&#39;s description (short text up to 512 characters). Users will see this text at the beginning of the conversation with the bot, titled &#39;What can this bot do?&#39;.&lt;/li&gt; &lt;li&gt;&lt;code&gt;/setabouttext&lt;/code&gt;: change the bot&#39;s about info, a shorter text up to 120 characters. Users will see this text on the bot&#39;s profile page. When they share your bot with someone, this text is sent together with the link.&lt;/li&gt; &lt;li&gt;&lt;code&gt;/setuserpic&lt;/code&gt;: change the bot&#39;s profile picture.&lt;/li&gt; &lt;li&gt;&lt;code&gt;/setcommands&lt;/code&gt;: change the list of commands supported by your bot. Users will see these commands as suggestions when they type / in the chat with your bot. See commands for more info.&lt;/li&gt; &lt;li&gt;&lt;code&gt;/setdomain&lt;/code&gt;: link a website domain to your bot. See the login widget section.&lt;/li&gt; &lt;li&gt;&lt;code&gt;/deletebot&lt;/code&gt;: delete your bot and free its username. Cannot be undone.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/pytelegrambotapi/#synchronous-telebot&#34;&gt;Synchronous TeleBot.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;telebot&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;API_TOKEN&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;api_token&amp;gt;&#39;&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;bot&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;telebot&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TeleBot&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;API_TOKEN&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;nd&#34;&gt;@bot&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;message_handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;commands&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;help&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;start&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;send_welcome&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;bot&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;reply_to&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;s2&#34;&gt;Hi there, I am EchoBot.&lt;/span&gt;
&lt;span class=&#34;s2&#34;&gt;I am here to echo your kind words back to you. Just say anything nice and I&#39;ll say the exact same thing to you!&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;s2&#34;&gt;&#34;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;nd&#34;&gt;@bot&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;message_handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;echo_message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;bot&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;reply_to&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;bot&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;infinity_polling&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/pytelegrambotapi/#asynchronous-telebot&#34;&gt;Asynchronous TeleBot.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;telebot.async_telebot&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;AsyncTeleBot&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;bot&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;AsyncTeleBot&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;TOKEN&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;nd&#34;&gt;@bot&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;message_handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;commands&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;help&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;start&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;send_welcome&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;bot&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;reply_to&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;s2&#34;&gt;Hi there, I am EchoBot.&lt;/span&gt;
&lt;span class=&#34;s2&#34;&gt;I am here to echo your kind words back to you. Just say anything nice and I&#39;ll say the exact same thing to you!&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;s2&#34;&gt;&#34;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;nd&#34;&gt;@bot&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;message_handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;echo_message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;bot&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;reply_to&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;asyncio&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bot&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;polling&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;libraries&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/python_gnupg/&#34;&gt;Libraries&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: How to encrypt a file.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;gpg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;encrypt_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;path/to/file&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;recipients&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where &lt;code&gt;recipients&lt;/code&gt; is a &lt;code&gt;List[str]&lt;/code&gt; of gpg Key IDs.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/python_gnupg/#list-the-recipients-that-can-decrypt-a-file&#34;&gt;List the recipients that can decrypt a file.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;list_recipients&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;GPGKey&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;List the keys that can decrypt a file.&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;    Args:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;       path: Path to the file to check.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    &#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;short_key&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gpg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_recipients_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)):&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gpg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;list_keys&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;short_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;][&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;fingerprint&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; feat(requests#Use a proxy): Use a proxy&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;http_proxy&lt;/span&gt;  &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;http://10.10.1.10:3128&#34;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;https_proxy&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;https://10.10.1.11:1080&#34;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;ftp_proxy&lt;/span&gt;   &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;ftp://10.10.1.10:3128&#34;&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;proxies&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;s2&#34;&gt;&#34;http&#34;&lt;/span&gt;  &lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;http_proxy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;s2&#34;&gt;&#34;https&#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;https_proxy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;s2&#34;&gt;&#34;ftp&#34;&lt;/span&gt;   &lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ftp_proxy&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;requests&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;proxies&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;proxies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce aiohttp.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://docs.aiohttp.org/en/stable/&#34;&gt;&lt;code&gt;aiohttp&lt;/code&gt;&lt;/a&gt; is an asynchronous HTTP Client/Server for asyncio and Python. Think of it as the &lt;code&gt;requests&lt;/code&gt; for asyncio.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aiohttp/#installation&#34;&gt;Installation&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aiohttp/#make-a-request&#34;&gt;How to make a request&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aiohttp/#passing-parameters-in-urls&#34;&gt;Passing parameters in urls&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aiohttp/#setting-custom-headers&#34;&gt;Setting custom headers&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aiohttp/#set-custom-cookies&#34;&gt;Set custom cookies&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aiohttp/#proxy-support&#34;&gt;Proxy support&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aiohttp/#how-to-use-the-clientSession&#34;&gt;How to use the &lt;code&gt;ClientSession&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aiohttp/#an-aiohttp-adapter&#34;&gt;An aiohttp adapter&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Receive keys from a keyserver.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;import_result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gpg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;recv_keys&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;server-name&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;keyid1&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;keyid2&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;configure-docker-to-host-the-application&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/&#34;&gt;Configure Docker to host the application&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_project_template/python_docker/#docker-python-not-showning-prints&#34;&gt;Troubleshoot Docker python not showning prints.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use &lt;code&gt;CMD [&#34;python&#34;,&#34;-u&#34;,&#34;main.py&#34;]&lt;/code&gt; instead of &lt;code&gt;CMD [&#34;python&#34;,&#34;main.py&#34;]&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: [Get the difference of two lists.](../coding/python/python_project_template/python_docker.md#prevent-pip-install--r-requirements.txt-to-run-on-each-docker-build:-prevent-&lt;code&gt;pip-install--r-requirements.txt&lt;/code&gt;-to-run-on-each-&lt;code&gt;docker-build&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;i&#39;m-assuming-that-at-some-point-in-your-build-process,-you&#39;re-copying-your-entire-application-into-the-docker-image-with-copy-or-add:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;copy-.-/opt/app
workdir-/opt/app
run-pip-install--r-requirements.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;the-problem-is-that-you&#39;re-invalidating-the-docker-build-cache-every-time-you&#39;re-copying-the-entire-application-into-the-image.-this-will-also-invalidate-the-cache-for-all-subsequent-build-steps.&lt;/p&gt; &lt;p&gt;to-prevent-this,-i&#39;d-suggest-copying-only-the-requirements.txt-file-in-a-separate-build-step-before-adding-the-entire-application-into-the-image:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;copy-requirements.txt-/opt/app/requirements.txt
workdir-/opt/app
run-pip-install--r-requirements.txt
copy-.-/opt/app
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;feat(python_snippets)&lt;/p&gt; &lt;pre&gt;&lt;code&gt;If we want to substract the elements of one list from the other you can use:

```python
for x in b:
  if x in a:
    a.remove(x)
```
&lt;/code&gt;&lt;/pre&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#override-entrypoint&#34;&gt;Override entrypoint.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;run&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-it&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--entrypoint&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/bin/bash&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;docker_image&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#disable-ipv6&#34;&gt;Disable ipv6.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sysctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;net.ipv6.conf.all.disable_ipv6&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
sysctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;net.ipv6.conf.default.disable_ipv6&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#remove-the-apt-cache-after-installing-a-package&#34;&gt;Remove the apt cache after installing a package.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;RUN apt-get update &amp;amp;&amp;amp; apt-get install -y \
  python3 \
  python3-pip \
  &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#add-the-contents-of-a-directory-to-the-docker&#34;&gt;Add the contents of a directory to the docker.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ADD ./path/to/directory /path/to/destination
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#add-healthcheck-to-your-dockers&#34;&gt;Add healthcheck to your dockers.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Health checks allow a container to expose its workload’s availability. This stands apart from whether the container is running. If your database goes down, your API server won’t be able to handle requests, even though its Docker container is still running.&lt;/p&gt; &lt;p&gt;This makes for unhelpful experiences during troubleshooting. A simple &lt;code&gt;docker ps&lt;/code&gt; would report the container as available. Adding a health check extends the &lt;code&gt;docker ps&lt;/code&gt; output to include the container’s true state.&lt;/p&gt; &lt;p&gt;You configure container health checks in your Dockerfile. This accepts a command which the Docker daemon will execute every 30 seconds. Docker uses the command’s exit code to determine your container’s healthiness:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;0&lt;/code&gt;: The container is healthy and working normally.&lt;/li&gt; &lt;li&gt;&lt;code&gt;1&lt;/code&gt;: The container is unhealthy; the workload may not be functioning.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Healthiness isn’t checked straightaway when containers are created. The status will show as starting before the first check runs. This gives the container time to execute any startup tasks. A container with a passing health check will show as healthy; an unhealthy container displays unhealthy.&lt;/p&gt; &lt;p&gt;In docker-compose you can write the healthchecks like the next snippet:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;3.4&#39;&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;jellyfin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;linuxserver/jellyfin:latest&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;container_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;jellyfin&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;restart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;unless-stopped&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;healthcheck&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;test&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;curl http://localhost:8096/health || exit 1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;10s&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;retries&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;5&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;start_period&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;5s&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;10s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#list-the-dockers-of-a-registry&#34;&gt;List the dockers of a registry.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;List all repositories (effectively images):&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-X&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;GET&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://myregistry:5000/v2/_catalog
&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;repositories&#34;&lt;/span&gt;:&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;redis&#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&#34;ubuntu&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;List all tags for a repository:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-X&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;GET&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://myregistry:5000/v2/ubuntu/tags/list
&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;name&#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&#34;ubuntu&#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&#34;tags&#34;&lt;/span&gt;:&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;14.04&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If the registry needs authentication you have to specify username and password in the curl command&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-X&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;GET&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-u&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://myregistry:5000/v2/_catalog
curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-X&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;GET&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-u&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://myregistry:5000/v2/ubuntu/tags/list
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/beautifulsoup/#searching-by-attribute-and-value&#34;&gt;Searching by attribute and value.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;soup&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;BeautifulSoup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;html&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;results&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;soup&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;findAll&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;td&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;valign&#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;top&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#installation&#34;&gt;Install a specific version of Docker.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Follow &lt;a href=&#34;https://docs.docker.com/engine/install/debian/&#34;&gt;these instructions&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If that doesn&#39;t install the version of &lt;code&gt;docker-compose&lt;/code&gt; that you want use &lt;a href=&#34;https://stackoverflow.com/questions/49839028/how-to-upgrade-docker-compose-to-latest-version&#34;&gt;the next snippet&lt;/a&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;VERSION&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--silent&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://api.github.com/repos/docker/compose/releases/latest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-Po&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&#34;tag_name&#34;: &#34;\K.*\d&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;DESTINATION&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/usr/local/bin/docker-compose
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-L&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://github.com/docker/compose/releases/download/&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;VERSION&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;/docker-compose-&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;uname&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;-&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;uname&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-m&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$DESTINATION&lt;/span&gt;
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;chmod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;755&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$DESTINATION&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you don&#39;t want the latest version set the &lt;code&gt;VERSION&lt;/code&gt; variable.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_project_template/python_docker/#using-pdm&#34;&gt;Dockerize a PDM application.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It is possible to use PDM in a multi-stage Dockerfile to first install the project and dependencies into &lt;code&gt;__pypackages__&lt;/code&gt; and then copy this folder into the final stage, adding it to &lt;code&gt;PYTHONPATH&lt;/code&gt;.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;python:3.11-slim-bookworm&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;builder&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pdm

&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pyproject.toml&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pdm.lock&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;README.md&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/project/
&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;src/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/project/src

&lt;span class=&#34;k&#34;&gt;WORKDIR&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/project&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mkdir&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;__pypackages__&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pdm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sync&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--prod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--no-editable

&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;python:3.11-slim-bookworm&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;ENV&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;PYTHONPATH&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/project/pkgs
&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--from&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;builder&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/project/__pypackages__/3.11/lib&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/project/pkgs

&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--from&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;builder&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/project/__pypackages__/3.11/bin/*&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/bin/

&lt;span class=&#34;k&#34;&gt;CMD&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;python&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;-m&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;project&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;click&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/click/&#34;&gt;Click&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Split stdout from stderr in tests.&lt;/p&gt; &lt;p&gt;By default the &lt;code&gt;runner&lt;/code&gt; is configured to mix &lt;code&gt;stdout&lt;/code&gt; and &lt;code&gt;stderr&lt;/code&gt;, if you wish to tell apart both sources use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;test&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;runner&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CliRunner&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
  &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;runner&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mix_stderr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/click/#file-system-isolation&#34;&gt;File system isolation.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You may need to isolate the environment variables if your application read the configuration from them. To do that override the &lt;code&gt;runner&lt;/code&gt; fixture:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nd&#34;&gt;@pytest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fixture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;runner&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;fixture_runner&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CliRunner&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Configure the Click cli test runner.&#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CliRunner&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;env&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
            &lt;span class=&#34;s1&#34;&gt;&#39;PASSWORD_STORE_DIR&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;s1&#34;&gt;&#39;GNUPGHOME&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;s1&#34;&gt;&#39;PASSWORD_AUTH_DIR&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;mix_stderr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you define the fixture in &lt;code&gt;conftest.py&lt;/code&gt; you may need to use another name than &lt;code&gt;runner&lt;/code&gt; otherwise it may be skipped, for example &lt;code&gt;cli_runner&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;sqlite&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/sqlite/&#34;&gt;SQLite&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/sqlite/#import-a-table-from-another-database&#34;&gt;Import a table from another database.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you have an SQLite databases named &lt;code&gt;database1&lt;/code&gt; with a table &lt;code&gt;t1&lt;/code&gt; and &lt;code&gt;database2&lt;/code&gt; with a table &lt;code&gt;t2&lt;/code&gt; and want to import table &lt;code&gt;t2&lt;/code&gt; from &lt;code&gt;database2&lt;/code&gt; into &lt;code&gt;database1&lt;/code&gt;. You need to open &lt;code&gt;database1&lt;/code&gt; with &lt;code&gt;litecli&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;litecli&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;database1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Attach the other database with the command:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ATTACH &#39;database2file&#39; AS db2;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then create the table &lt;code&gt;t2&lt;/code&gt;, and copy the data over with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;INSERT INTO t2 SELECT * FROM db2.t2;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;promql&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/promql/promql/&#34;&gt;Promql&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/promql/promql/#usage&#34;&gt;Add basic operations.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Selecting series:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Select latest sample for series with a given metric name:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;node_cpu_seconds_total&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Select 5-minute range of samples for series with a given metric name:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;node_cpu_seconds_total&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;5m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Only series with given label values:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;node_cpu_seconds_total&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nl&#34;&gt;cpu&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&#34;,&lt;/span&gt;&lt;span class=&#34;nl&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;idle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&#34;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Complex label matchers (&lt;code&gt;=&lt;/code&gt;: equality, &lt;code&gt;!=&lt;/code&gt;: non-equality, &lt;code&gt;=~&lt;/code&gt;: regex match, &lt;code&gt;!~&lt;/code&gt;: negative regex match):&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;node_cpu_seconds_total&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nl&#34;&gt;cpu&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&#34;,&lt;/span&gt;&lt;span class=&#34;nl&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=~&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;user|system&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&#34;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Select data from one day ago and shift it to the current time:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;process_resident_memory_bytes&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;1d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Rates of increase for counters:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Per-second rate of increase, averaged over last 5 minutes:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;rate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;demo_api_request_duration_seconds_count&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;5m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Per-second rate of increase, calculated over last two samples in a 1-minute time window:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;irate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;demo_api_request_duration_seconds_count&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;1m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Absolute increase over last hour:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;increase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;demo_api_request_duration_seconds_count&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;1h&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Aggregating over multiple series:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Sum over all series:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;sum&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;node_filesystem_size_bytes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Preserve the instance and job label dimensions:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;sum&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;by&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;job&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;instance&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;node_filesystem_size_bytes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Aggregate away the instance and job label dimensions:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;sum&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;without&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;instance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;job&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;node_filesystem_size_bytes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Available aggregation operators: &lt;code&gt;sum()&lt;/code&gt;, &lt;code&gt;min()&lt;/code&gt;, &lt;code&gt;max()&lt;/code&gt;, &lt;code&gt;avg()&lt;/code&gt;, &lt;code&gt;stddev()&lt;/code&gt;, &lt;code&gt;stdvar()&lt;/code&gt;, &lt;code&gt;count()&lt;/code&gt;, &lt;code&gt;count_values()&lt;/code&gt;, &lt;code&gt;group()&lt;/code&gt;, &lt;code&gt;bottomk()&lt;/code&gt;, &lt;code&gt;topk()&lt;/code&gt;, &lt;code&gt;quantile()&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Time:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Get the Unix time in seconds at each resolution step:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Get the age of the last successful batch job run:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;demo_batch_last_success_timestamp_seconds&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Find batch jobs which haven&#39;t succeeded in an hour:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;demo_batch_last_success_timestamp_seconds&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3600&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/promql/promql/#run-operation-only-on-the-elements-that-match-a-condition&#34;&gt;Run operation only on the elements that match a condition.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Imagine we want to run the &lt;code&gt;zfs_dataset_used_bytes - zfs_dataset_used_by_dataset_bytes&lt;/code&gt; operation only on the elements that match &lt;code&gt;zfs_dataset_used_by_dataset_bytes &amp;gt; 200e3&lt;/code&gt;. You can do this with &lt;code&gt;and&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zfs_dataset_used_bytes - zfs_dataset_used_by_dataset_bytes and zfs_dataset_used_by_dataset_bytes &amp;gt; 200e3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/promql/promql/#substracting-two-metrics&#34;&gt;Substracting two metrics.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To run binary operators between vectors you need them to match. Basically it means that it will only do the operation on the elements that have the same labels. Sometimes you want to do operations on metrics that don&#39;t have the same labels. In those cases you can use the &lt;code&gt;on&lt;/code&gt; operator. Imagine that we want to substract the next vectors:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zfs_dataset_used_bytes{type=&#39;filesystem&#39;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;And&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sum by (hostname,filesystem) (zfs_dataset_used_bytes{type=&#39;snapshot&#39;})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;That only have in common the labels &lt;code&gt;hostname&lt;/code&gt; and filesystem`.&lt;/p&gt; &lt;p&gt;You can use the next expression then:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zfs_dataset_used_bytes{type=&#39;filesystem&#39;} - on (hostname, filesystem) sum by (hostname,filesystem) (zfs_dataset_used_bytes{type=&#39;snapshot&#39;})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To learn more on Vector matching read &lt;a href=&#34;https://iximiuz.com/en/posts/prometheus-vector-matching/&#34;&gt;this article&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/promql/promql/#ranges-only-allowed-for-vector-selectors&#34;&gt;Ranges only allowed for vector selectors.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You may need to specify a subquery range such as &lt;code&gt;[1w:1d]&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;logql&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/logql/&#34;&gt;Logql&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce LogQL.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://grafana.com/docs/loki/latest/logql/&#34;&gt;LogQL&lt;/a&gt; is Grafana Loki’s PromQL-inspired query language. Queries act as if they are a distributed &lt;code&gt;grep&lt;/code&gt; to aggregate log sources. LogQL uses labels and operators for filtering.&lt;/p&gt; &lt;p&gt;There are two types of LogQL queries:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Log queries: Return the contents of log lines.&lt;/li&gt; &lt;li&gt;Metric queries: Extend log queries to calculate values based on query results.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/logql/#apply-a-pattern-to-the-value-of-a-label&#34;&gt;Apply a pattern to the value of a label.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Some logs are sent in json and then one of their fields can contain other structured data. You may want to use that structured data to further filter the logs.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;{app=&#34;ingress-nginx&#34;} | json | line_format `{{.log}}` | pattern `&amp;lt;_&amp;gt; - - &amp;lt;_&amp;gt; &#34;&amp;lt;method&amp;gt; &amp;lt;_&amp;gt; &amp;lt;_&amp;gt;&#34; &amp;lt;status&amp;gt; &amp;lt;_&amp;gt; &amp;lt;_&amp;gt; &#34;&amp;lt;_&amp;gt;&#34; &amp;lt;_&amp;gt;` | method != `GET`
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;{app=&#34;ingress-nginx&#34;}&lt;/code&gt;: Show only the logs of the &lt;code&gt;ingress-nginx&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;&lt;code&gt;| json&lt;/code&gt;: Interpret the line as a json.&lt;/li&gt; &lt;li&gt;&lt;code _.log=&#34;{.log&#34;&gt;``| line_format&lt;/code&gt;}&lt;code&gt;| pattern&lt;/code&gt;&amp;lt;&lt;em&gt;&amp;gt; - - &amp;lt;&lt;/em&gt;&amp;gt; &#34;&lt;method&gt; &amp;lt;&lt;em&gt;&amp;gt; &amp;lt;&lt;/em&gt;&amp;gt;&#34; &lt;status&gt; &amp;lt;&lt;em&gt;&amp;gt; &amp;lt;&lt;/em&gt;&amp;gt; &#34;&amp;lt;&lt;em&gt;&amp;gt;&#34; &amp;lt;&lt;/em&gt;&amp;gt;&lt;code&gt;```: interpret the&lt;/code&gt;log` json field of the trace with the selected pattern&lt;/status&gt;&lt;/method&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;``| method !=&lt;/code&gt;GET````: Filter the line using a key extracted by the pattern.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/logql/#count-the-unique-values-of-a-label&#34;&gt;Count the unique values of a label.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Sometimes you want to alert on the values of a log. For example if you want to make sure that you&#39;re receiving the logs from more than 20 hosts (otherwise something is wrong). Assuming that your logs attach a &lt;code&gt;host&lt;/code&gt; label you can run&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sum(count by(host) (rate({host=~&#34;.+&#34;} [24h])) &amp;gt; bool 0)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This query will: - &lt;code&gt;{host=~&#34;.+&#34;}&lt;/code&gt;: Fetch all log lines that contain the label &lt;code&gt;host&lt;/code&gt; - &lt;code&gt;count by(host) (rate({host=~&#34;.+&#34;} [24h])&lt;/code&gt;: Calculates the number of entries in the last 24h. - &lt;code&gt;count by(host) (rate({host=~&#34;.+&#34;} [24h])) &amp;gt; bool 0&lt;/code&gt;: Converts to &lt;code&gt;1&lt;/code&gt; all the vector elements that have more than 1 message. - &lt;code&gt;sum(count by(host) (rate({host=~&#34;.+&#34;} [24h])) &amp;gt; bool 0)&lt;/code&gt;: Sums all the vector elements to get the number of hosts that have more than one message.&lt;/p&gt; &lt;p&gt;&lt;code&gt;journald&lt;/code&gt; promtail parser is known to fail between upgrades, it&#39;s useful too to make an alert to make sure that all your hosts are sending the traces. You can do it with: &lt;code&gt;sum(count by(host) (rate({job=&#34;systemd-journal&#34;} [24h])) &amp;gt; bool 0)&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pytest&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/pytest-xprocess/&#34;&gt;Pytest&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pytest/#stop-pytest-right-at-the-start-if-condition-not-met&#34;&gt;Stop pytest right at the start if condition not met.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use the &lt;code&gt;pytest_configure&lt;/code&gt; &lt;a href=&#34;https://docs.pytest.org/en/4.6.x/reference.html#initialization-hooks&#34;&gt;initialization hook&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;In your global &lt;code&gt;conftest.py&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;requests&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pytest&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;pytest_configure&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;requests&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;http://localhost:9200&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;requests&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exceptions&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ConnectionError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;msg&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;FATAL. Connection refused: ES does not appear to be installed as a service (localhost port 9200)&#39;&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;pytest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Note that the single argument of &lt;code&gt;pytest_configure&lt;/code&gt; has to be named &lt;code&gt;config&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;Using &lt;code&gt;pytest.exit&lt;/code&gt; makes it look nicer.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce pytest-xprocess.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/pytest-dev/pytest-xprocess&#34;&gt;&lt;code&gt;pytest-xprocess&lt;/code&gt;&lt;/a&gt; is a pytest plugin for managing external processes across test runs.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://pytest-xprocess.readthedocs.io/en/latest/#quickstart&#34;&gt;Installation&lt;/a&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pytest-xprocess
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;a href=&#34;https://pytest-xprocess.readthedocs.io/en/latest/#quickstart&#34;&gt;Usage&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;Define your process fixture in &lt;code&gt;conftest.py&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pytest&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;xprocess&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ProcessStarter&lt;/span&gt;

&lt;span class=&#34;nd&#34;&gt;@pytest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fixture&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;myserver&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xprocess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Starter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ProcessStarter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;# startup pattern&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;pattern&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;[Ss]erver has started!&#34;&lt;/span&gt;

        &lt;span class=&#34;c1&#34;&gt;# command to start process&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;command&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;arg1&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;arg2&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;# ensure process is running and return its logfile&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;logfile&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;xprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ensure&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;myserver&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Starter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;conn&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# create a connection or url/port info to the server&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;yield&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;conn&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;# clean up whole process tree afterwards&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;xprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getinfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;myserver&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;terminate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Now you can use this fixture in any test functions where &lt;code&gt;myserver&lt;/code&gt; needs to be up and &lt;code&gt;xprocess&lt;/code&gt; will take care of it for you.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://pytest-xprocess.readthedocs.io/en/latest/starter.html#matching-process-output-with-pattern&#34;&gt;Matching process output with pattern&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;In order to detect that your process is ready to answer queries, &lt;code&gt;pytest-xprocess&lt;/code&gt; allows the user to provide a string pattern by setting the class variable pattern in the Starter class. &lt;code&gt;pattern&lt;/code&gt; will be waited for in the process &lt;code&gt;logfile&lt;/code&gt; for a maximum time defined by &lt;code&gt;timeout&lt;/code&gt; before timing out in case the provided pattern is not matched.&lt;/p&gt; &lt;p&gt;It’s important to note that pattern is a regular expression and will be matched using python &lt;code&gt;re.search&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://pytest-xprocess.readthedocs.io/en/latest/starter.html#controlling-startup-wait-time-with-timeout&#34;&gt;Controlling Startup Wait Time with timeout&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;Some processes naturally take longer to start than others. By default, &lt;code&gt;pytest-xprocess&lt;/code&gt; will wait for a maximum of 120 seconds for a given process to start before raising a &lt;code&gt;TimeoutError&lt;/code&gt;. Changing this value may be useful, for example, when the user knows that a given process would never take longer than a known amount of time to start under normal circunstancies, so if it does go over this known upper boundary, that means something is wrong and the waiting process must be interrupted. The maximum wait time can be controlled through the class variable timeout.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;   &lt;span class=&#34;nd&#34;&gt;@pytest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fixture&lt;/span&gt;
   &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;myserver&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xprocess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
       &lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Starter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ProcessStarter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
           &lt;span class=&#34;c1&#34;&gt;# will wait for 10 seconds before timing out&lt;/span&gt;
           &lt;span class=&#34;n&#34;&gt;timeout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Passing command line arguments to your process with &lt;code&gt;args&lt;/code&gt;:&lt;/p&gt; &lt;p&gt;In order to start a process, pytest-xprocess must be given a command to be passed into the subprocess.Popen constructor. Any arguments passed to the process command can also be passed using args. As an example, if I usually use the following command to start a given process:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;myproc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;bacon&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-cores&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;destdir&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;That would look like:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;args&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;myproc&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;-name&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&#34;bacon&#34;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;-cores&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;destdir&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;when using args in pytest-xprocess to start the same process.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nd&#34;&gt;@pytest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fixture&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;myserver&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xprocess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Starter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ProcessStarter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;# will pass &#34;$&amp;gt; myproc -name &#34;bacon&#34; -cores 4 &amp;lt;destdir&amp;gt;&#34;  to the&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;# subprocess.Popen constructor so the process can be started with&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;# the given arguments&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;myproc&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;-name&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&#34;bacon&#34;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;-cores&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;destdir&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;

        &lt;span class=&#34;c1&#34;&gt;# ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;python-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/&#34;&gt;Python Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#substract-two-paths&#34;&gt;Substract two paths.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It can also framed to how to get the relative path between two absolute paths:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pathlib&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;/home/lyz/&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;h&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;/home/&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;relative_to&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;h&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;PosixPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;lyz&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#copy-files-from-a-python-package&#34;&gt;Copy files from a python package.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;pkgdir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;modules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;mypkg&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;__path__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;fullpath&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;join&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pkgdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;myfile&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;shutil&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;copy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fullpath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getcwd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#sort-the-returned-paths-of-glob&#34;&gt;Sort the returned paths of glob.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;glob&lt;/code&gt; order is arbitrary, but you can sort them yourself.&lt;/p&gt; &lt;p&gt;If you want sorted by name:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;sorted&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;glob&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;glob&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;*.png&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;sorted by modification time:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;sorted&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;glob&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;glob&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;*.png&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getmtime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;sorted by size:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;sorted&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;glob&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;glob&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;*.png&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getsize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#read-file-with-pathlib&#34;&gt;Read file with Pathlib.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;file_&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;/to/some/file&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;file_&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read_text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-changed-time-of-a-file&#34;&gt;Get changed time of a file.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getmtime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#configure-the-logging-of-a-program-to-look-nice&#34;&gt;Configure the logging of a program to look nice.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;load_logger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;verbose&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bool&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# pragma no cover&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Configure the Logging logger.&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;    Args:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        verbose: Set the logging level to Debug.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    &#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;addLevelName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INFO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\033&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;[36mINFO&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\033&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;[0m&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;addLevelName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ERROR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\033&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;[31mERROR&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\033&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;[0m&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;addLevelName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DEBUG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\033&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;[32mDEBUG&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\033&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;[0m&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;addLevelName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WARNING&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\033&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;[33mWARNING&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\033&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;[0m&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;verbose&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;basicConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
            &lt;span class=&#34;nb&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%(asctime)s&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%(levelname)s&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%(name)s&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%(message)s&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;stream&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DEBUG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;datefmt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;%Y-%m-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%d&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; %H:%M:%S&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;telebot&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setLevel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DEBUG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# Outputs debug messages to console.&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;basicConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;stream&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INFO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%(levelname)s&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%(message)s&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-the-modified-time-of-a-file-with-pathlib&#34;&gt;Get the modified time of a file with Pathlib.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;file_&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;/to/some/file&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;file_&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;st_mtime&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can also access:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Created time: with &lt;code&gt;st_ctime&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Accessed time: with &lt;code&gt;st_atime&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;They are timestamps, so if you want to compare it with a datetime object use the &lt;code&gt;timestamp&lt;/code&gt; method:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timestamp&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file_&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;st_mtime&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;60&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#show-the-date-in-the-logging-module-traces&#34;&gt;Show the date in the logging module traces.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To display the date and time of an event, you would place &lt;code&gt;%(asctime)s&lt;/code&gt; in your format string:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;logging&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;basicConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%(asctime)s&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%(message)s&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;warning&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;is when this event was logged.&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#remove-html-url-characters&#34;&gt;Remove html url characters.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To transform an URL string into normal string, for example replacing &lt;code&gt;%20&lt;/code&gt; with space use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;urllib.parse&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;unquote&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;unquote&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;%CE%B1%CE%BB%20&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;αλ&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;jinja2&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/python_jinja2/&#34;&gt;Jinja2&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/python_jinja2/#escape-jinja-expansion-on-a-jinja-template&#34;&gt;Escape jinja expansion on a jinja template.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;{%&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;raw&lt;/span&gt; &lt;span class=&#34;cp&#34;&gt;%}&lt;/span&gt;

Anything in this block is treated as raw text,
including {{ curly braces }} and
{% other block-like syntax %}

&lt;span class=&#34;cp&#34;&gt;{%&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;endraw&lt;/span&gt; &lt;span class=&#34;cp&#34;&gt;%}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;mkdocstrings&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/mkdocstrings/&#34;&gt;mkdocstrings&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Correct the watch directive.&lt;/p&gt; &lt;p&gt;&lt;code&gt;watch&lt;/code&gt; is a list of directories to watch while serving the documentation. So if any file is changed in those directories, the documentation is rebuilt.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pydantic&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pydantic/&#34;&gt;Pydantic&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pydantic/#to-investigate&#34;&gt;Investigate libraries.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://pandera.readthedocs.io/en/stable/pydantic_integration.html&#34;&gt;Integration of pydantic with pandas&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pydantic/#initialize-attributes-at-object-creation&#34;&gt;Initialize attributes at object creation.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;pydantic&lt;/code&gt; recommends &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pydantic/#using-root-validators&#34;&gt;using root validators&lt;/a&gt;, but it&#39;s difficult to undestand how to do it and to debug the errors. You also don&#39;t have easy access to the default values of the model. I&#39;d rather use the &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pydantic/#overwriting-the-__init__-method&#34;&gt;overwriting the &lt;code&gt;__init__&lt;/code&gt; method&lt;/a&gt;.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;fish&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BaseModel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__init__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kwargs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;nb&#34;&gt;super&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;fm&#34;&gt;__init__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kwargs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Fish initialization successful!&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;complex_function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;python-telegram&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/python-telegram/&#34;&gt;Python Telegram&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Analyze the different python libraries to interact with telegram.&lt;/p&gt; &lt;p&gt;There are two ways to interact with Telegram through python:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Client libraries&lt;/li&gt; &lt;li&gt;Bot libraries&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Client libraries:&lt;/p&gt; &lt;p&gt;Client libraries use your account to interact with Telegram itself through a developer API token.&lt;/p&gt; &lt;p&gt;The most popular to use is &lt;a href=&#34;https://docs.telethon.dev/en/stable/index.html&#34;&gt;Telethon&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Bot libraries:&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://core.telegram.org/bots/samples#python&#34;&gt;Telegram lists many libraries to interact with the bot API&lt;/a&gt;, the most interesting are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;#python-telegram-bot&#34;&gt;python-telegram-bot&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#pytelegrambotapi&#34;&gt;pyTelegramBotAPI&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#aiogram&#34;&gt;aiogram&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;If there comes a moment when we have to create the messages ourselves, &lt;a href=&#34;https://telegram-text.alinsky.tech/api_reference&#34;&gt;telegram-text&lt;/a&gt; may be an interesting library to check.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/python-telegram-bot/python-telegram-bot&#34;&gt;python-telegram-bot&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;Pros:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Popular: 23k stars, 4.9k forks&lt;/li&gt; &lt;li&gt;Maintained: last commit 3 days ago&lt;/li&gt; &lt;li&gt;They have a developers community to get help in &lt;a href=&#34;https://telegram.me/pythontelegrambotgroup&#34;&gt;this telegram group&lt;/a&gt;&lt;/li&gt; &lt;li&gt;I like how they try to minimize third party dependencies, and how you can install the complements if you need them&lt;/li&gt; &lt;li&gt;Built on top of asyncio&lt;/li&gt; &lt;li&gt;Nice docs&lt;/li&gt; &lt;li&gt;Fully supports the &lt;a href=&#34;https://core.telegram.org/bots/api&#34;&gt;Telegram bot API&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Has many examples&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Cons:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Interface is a little verbose and complicated at a first look&lt;/li&gt; &lt;li&gt;Only to be run in a single thread (not a problem)&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;References:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://docs.python-telegram-bot.org/&#34;&gt;Package documentation&lt;/a&gt; is the technical reference for python-telegram-bot. It contains descriptions of all available classes, modules, methods and arguments as well as the changelog.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/python-telegram-bot/python-telegram-bot/wiki/&#34;&gt;Wiki&lt;/a&gt; is home to number of more elaborate introductions of the different features of python-telegram-bot and other useful resources that go beyond the technical documentation.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://docs.python-telegram-bot.org/examples.html&#34;&gt;Examples&lt;/a&gt; section contains several examples that showcase the different features of both the Bot API and python-telegram-bot&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/python-telegram-bot/python-telegram-bot&#34;&gt;Source&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/eternnoir/pyTelegramBotAPI&#34;&gt;pyTelegramBotAPI&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;Pros:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Popular: 7.1k stars, 1.8k forks&lt;/li&gt; &lt;li&gt;Maintained: last commit 3 weeks ago&lt;/li&gt; &lt;li&gt;Both sync and async&lt;/li&gt; &lt;li&gt;Nicer interface with decorators and simpler setup&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/eternnoir/pyTelegramBotAPI#sending-large-text-messages&#34;&gt;They have an example on how to split long messages&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/eternnoir/pyTelegramBotAPI#testing&#34;&gt;Nice docs on how to test&lt;/a&gt;&lt;/li&gt; &lt;li&gt;They have a developers community to get help in &lt;a href=&#34;https://telegram.me/joinchat/Bn4ixj84FIZVkwhk2jag6A&#34;&gt;this telegram group&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Fully supports the &lt;a href=&#34;https://core.telegram.org/bots/api&#34;&gt;Telegram bot API&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Has examples&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Cons:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Uses lambdas inside the decorators, I don&#39;t know why it does it.&lt;/li&gt; &lt;li&gt;The docs are not as throughout as &lt;code&gt;python-telegram-bot&lt;/code&gt; one.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;References:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://pytba.readthedocs.io/en/latest/index.html&#34;&gt;Documentation&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/eternnoir/pyTelegramBotAPI&#34;&gt;Source&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/eternnoir/pyTelegramBotAPI/tree/master/examples/asynchronous_telebot&#34;&gt;Async Examples&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/aiogram/aiogram&#34;&gt;aiogram&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;Pros:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Popular: 3.8k stars, 717k forks&lt;/li&gt; &lt;li&gt;Maintained: last commit 4 days ago&lt;/li&gt; &lt;li&gt;Async support&lt;/li&gt; &lt;li&gt;They have a developers community to get help in &lt;a href=&#34;https://t.me/aiogram&#34;&gt;this telegram group&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Has type hints&lt;/li&gt; &lt;li&gt;Cleaner interface than &lt;code&gt;python-telegram-bot&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Fully supports the &lt;a href=&#34;https://core.telegram.org/bots/api&#34;&gt;Telegram bot API&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Has examples&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Cons:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Less popular than &lt;code&gt;python-telegram-bot&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Docs are written at a developer level, difficult initial barrier to understand how to use it.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;References:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://docs.aiogram.dev/en/dev-3.x/&#34;&gt;Documentation&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/aiogram/aiogram&#34;&gt;Source&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/aiogram/aiogram/tree/dev-3.x/examples&#34;&gt;Examples&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Conclusion:&lt;/p&gt; &lt;p&gt;Even if &lt;code&gt;python-telegram-bot&lt;/code&gt; is the most popular and with the best docs, I prefer one of the others due to the easier interface. &lt;code&gt;aiogram&lt;/code&gt;s documentation is kind of crap, and as it&#39;s the first time I make a bot I&#39;d rather have somewhere good to look at.&lt;/p&gt; &lt;p&gt;So I&#39;d say to go first with &lt;code&gt;pyTelegramBotAPI&lt;/code&gt; and if it doesn&#39;t go well, fall back to &lt;code&gt;python-telegram-bot&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;questionary&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/questionary/&#34;&gt;questionary&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/questionary/#autocomplete-answers&#34;&gt;Autocomplete answers.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you want autocomplete with fuzzy finding use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;questionary&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;prompt_toolkit.completion&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FuzzyWordCompleter&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;questionary&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;autocomplete&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;Save to (q to cancel): &#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;choices&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;destination_directories&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;completer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FuzzyWordCompleter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;destination_directories&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ask&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;rich&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/rich/&#34;&gt;rich&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/rich/#tree&#34;&gt;Tree console view.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Rich has a &lt;a href=&#34;https://rich.readthedocs.io/en/latest/reference/tree.html#rich.tree.Tree&#34;&gt;&lt;code&gt;Tree&lt;/code&gt;&lt;/a&gt; class which can generate a tree view in the terminal. A tree view is a great way of presenting the contents of a filesystem or any other hierarchical data. Each branch of the tree can have a label which may be text or any other Rich renderable.&lt;/p&gt; &lt;p&gt;The following code creates and prints a tree with a simple text label:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;rich.tree&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Tree&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;rich&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;tree&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Tree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Rich Tree&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;With only a single &lt;code&gt;Tree&lt;/code&gt; instance this will output nothing more than the text “Rich Tree”. Things get more interesting when we call &lt;code&gt;add()&lt;/code&gt; to add more branches to the &lt;code&gt;Tree&lt;/code&gt;. The following code adds two more branches:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;tree&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;foo&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;tree&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;bar&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The &lt;code&gt;tree&lt;/code&gt; will now have two branches connected to the original tree with guide lines.&lt;/p&gt; &lt;p&gt;When you call &lt;code&gt;add()&lt;/code&gt; a new &lt;code&gt;Tree&lt;/code&gt; instance is returned. You can use this instance to add more branches to, and build up a more complex tree. Let’s add a few more levels to the tree:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;baz_tree&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tree&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;baz&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;baz_tree&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;[red]Red&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;[green]Green&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;[blue]Blue&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;selenium&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/selenium/&#34;&gt;Selenium&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/selenium/#solve-element-isn&#39;t-clickable-in-headless-mode&#34;&gt;Solve element isn&#39;t clickable in headless mode.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;There are many things you can try to fix this issue. Being the first to configure the &lt;code&gt;driver&lt;/code&gt; to use the full screen. Assuming you&#39;re using the &lt;a href=&#34;#use-undetected-chromedriver&#34;&gt;undetectedchromedriver&lt;/a&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;undetected_chromedriver.v2&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;uc&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;options&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;uc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ChromeOptions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;options&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;--disable-dev-shm-usage&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;options&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;--no-sandbox&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;options&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;--headless&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;options&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;--start-maximized&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;options&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;--window-size=1920,1080&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;driver&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;uc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Chrome&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;options&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If that doesn&#39;t solve the issue use the next function:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;click&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;driver&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;uc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Chrome&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;xpath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Optional&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Click the element marked by the XPATH.&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;    Args:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        driver: Object to interact with selenium.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        xpath: Identifier of the element to click.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        mode: Type of click. It needs to be one of [None, position, wait]&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;    The different ways to click are:&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;    * None: The normal click of the driver.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    * wait: Wait until the element is clickable and then click it.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    * position: Deduce the position of the element and then click it with a javascript script.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    &#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mode&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
       &lt;span class=&#34;n&#34;&gt;driver&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;find_element&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;By&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;XPATH&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;xpath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;click&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;elif&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mode&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;wait&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;# https://stackoverflow.com/questions/59808158/element-isnt-clickable-in-headless-mode&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;WebDriverWait&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;driver&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;until&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;EC&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;element_to_be_clickable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;By&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;XPATH&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;xpath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;click&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;elif&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mode&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;position&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;# https://stackoverflow.com/questions/16807258/selenium-click-at-certain-position&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;element&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;driver&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;find_element&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;By&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;XPATH&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;xpath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;driver&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;execute_script&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;arguments[0].click();&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;element&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;sh&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/python_sh/&#34;&gt;sh&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/python_sh/#passing-environmental-variables-to-commands&#34;&gt;Passing environmental variables to commands.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The &lt;code&gt;_env&lt;/code&gt; special &lt;code&gt;kwarg&lt;/code&gt; allows you to pass a dictionary of environment variables and their corresponding values:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;sh&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;sh&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;google_chrome&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_env&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;SOCKS_SERVER&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;localhost:1234&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;code&gt;_env&lt;/code&gt; replaces your process’s environment completely. Only the key-value pairs in &lt;code&gt;_env&lt;/code&gt; will be used for its environment. If you want to add new environment variables for a process in addition to your existing environment, try something like this:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;sh&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;new_env&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;environ&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;copy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;new_env&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;SOCKS_SERVER&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;localhost:1234&#34;&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;sh&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;google_chrome&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_env&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new_env&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/python_sh/#use-commands-that-return-a-syntaxerror&#34;&gt;Use commands that return a SyntaxError.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;pass&lt;/code&gt; is a reserved python word so &lt;code&gt;sh&lt;/code&gt; fails when calling the password store command &lt;code&gt;pass&lt;/code&gt;.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;pass_command&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sh&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Command&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;pass&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;pass_command&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;show&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;new_file&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;typer&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/typer/&#34;&gt;Typer&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/typer/#print-to-stderr&#34;&gt;Print to stderr.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can print to &#34;standard error&#34; with a Rich &lt;code&gt;Console(stderr=True)&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;rich.console&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Console&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;err_console&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;err_console&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;error message&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;generic-coding-practices&#34;&gt;Generic Coding Practices&lt;/h3&gt; &lt;h4 id=&#34;how-to-code&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/how_to_code/&#34;&gt;How to code&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Personal evolution on how I code.&lt;/p&gt; &lt;p&gt;Over the years I&#39;ve tried different ways of developing my code:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Mindless coding: write code as you need to make it work, with no tests, documentation or any quality measure.&lt;/li&gt; &lt;li&gt;TDD.&lt;/li&gt; &lt;li&gt;Try to abstract everything to minimize the duplication of code between projects.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Each has it&#39;s advantages and disadvantages. After trying them all and given that right now I only have short spikes of energy and time to invest in coding my plan is to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Make the minimum effort to design the minimum program able to solve the problem at hand. This design will be represented in an &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/&#34;&gt;orgmode&lt;/a&gt; task.&lt;/li&gt; &lt;li&gt;Write the minimum code to make it work without thinking of tests or generalization, but with the &lt;a href=&#34;https://lyz-code.github.io/blue-book/architecture/domain_driven_design/&#34;&gt;domain driven design&lt;/a&gt; concepts so the code remains flexible and maintainable.&lt;/li&gt; &lt;li&gt;Once it&#39;s working see if I have time to improve it:&lt;/li&gt; &lt;li&gt;Create the tests to cover the critical functionality (no more 100% coverage).&lt;/li&gt; &lt;li&gt;If I need to make a package or the program evolves into something complex I&#39;d use &lt;a href=&#34;https://github.com/lyz-code/cookiecutter-python-project&#34;&gt;this scaffold template&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Once the spike is over I&#39;ll wait for a new spike to come either because I have time or because something breaks and I need to fix it.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;git&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/git/&#34;&gt;Git&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/git/#set-the-upstream-remote-by-default&#34;&gt;Set the upstream remote by default.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;config&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--global&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--add&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push.default&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;current
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;config&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--global&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--add&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push.autoSetupRemote&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/git/#remove-tags&#34;&gt;Remove tags.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To delete a tag you can run:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tag&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;tag_name&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To remove them remotely do&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--delete&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;origin&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tag_name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;devops&#34;&gt;DevOps&lt;/h2&gt; &lt;h3 id=&#34;infrastructure-as-code&#34;&gt;Infrastructure as Code&lt;/h3&gt; &lt;h4 id=&#34;ansible-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/forgejo/&#34;&gt;Ansible Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Forgejo.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://forgejo.org/&#34;&gt;Forgejo&lt;/a&gt; is a self-hosted lightweight software forge. Easy to install and low maintenance, it just does the job. The awful name comes from &lt;code&gt;forĝejo&lt;/code&gt;, the Esperanto word for forge. I kind of like though the concept of forge for the repositories.&lt;/p&gt; &lt;p&gt;Brought to you by an inclusive community under the umbrella of &lt;a href=&#34;https://forgejo.org/faq/#what-is-codeberg-ev&#34;&gt;Codeberg e.V.&lt;/a&gt;, a democratic non-profit organization, Forgejo can be trusted to be exclusively Free Software. It is a &lt;a href=&#34;https://codeberg.org/forgejo/forgejo/src/branch/forgejo/CONTRIBUTING/WORKFLOW.md#feature-branches&#34;&gt;&#34;soft&#34; fork of Gitea&lt;/a&gt; with a focus on scaling, federation and privacy.&lt;/p&gt; &lt;p&gt;In October 2022 the domains and trademark of Gitea were transferred to a for-profit company without knowledge or approval of the community. Despite &lt;a href=&#34;https://gitea-open-letter.coding.social/&#34;&gt;writing an open letter&lt;/a&gt;, the takeover was later confirmed. The goal of Forgejo is to continue developing the code with a healthy democratic governance.&lt;/p&gt; &lt;p&gt;On the 15&lt;sup&gt;th&lt;/sup&gt; of December of 2022 the &lt;a href=&#34;https://forgejo.org/2022-12-15-hello-forgejo/&#34;&gt;project was born&lt;/a&gt; with these major objectives:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The community is in control, and ensures we develop to address community needs.&lt;/li&gt; &lt;li&gt;We will help liberate software development from the shackles of proprietary tools.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;One of the approaches to achieve the last point is through pushing for &lt;a href=&#34;https://forgejo.org/2023-01-10-answering-forgejo-federation-questions/&#34;&gt;the Forgejo federation&lt;/a&gt; a much needed feature in the git web application ecosystem.&lt;/p&gt; &lt;p&gt;On the 29&lt;sup&gt;th&lt;/sup&gt; of December of 2022 they released &lt;a href=&#34;https://forgejo.org/2022-12-29-release-v1-18-0&#34;&gt;the first stable release&lt;/a&gt; and they have released several security releases between then and now.&lt;/p&gt; &lt;p&gt;Despite what you choose, the good thing is that as long as it&#39;s a soft fork &lt;a href=&#34;https://forgejo.org/faq/#are-migrations-between-gitea-and-forgejo-possible&#34;&gt;migrating between these software&lt;/a&gt; should be straight forward.&lt;/p&gt; &lt;p&gt;Forgejo outshines Gitea in:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Being built up by the people for the people. The project may die but it&#39;s not likely it will follow Gitea&#39;s path.&lt;/li&gt; &lt;li&gt;They are transparent regarding the &lt;a href=&#34;https://codeberg.org/forgejo/governance&#34;&gt;gobernance of the project&lt;/a&gt; which is created through &lt;a href=&#34;https://codeberg.org/forgejo/discussions/issues&#34;&gt;open community discussions&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;It&#39;s a political project that fights for the people&#39;s rights, for example through &lt;a href=&#34;https://forgejo.org/2023-01-10-answering-forgejo-federation-questions/&#34;&gt;federation&lt;/a&gt; and freely incorporating the new additions of Gitea&lt;/li&gt; &lt;li&gt;They&#39;ll eventually &lt;a href=&#34;https://codeberg.org/forgejo/discussions/issues/6&#34;&gt;have a better license&lt;/a&gt;&lt;/li&gt; &lt;li&gt;They get all the features and fixes of Gitea plus the contributions of the developers of the community that run out of Gitea.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Gitea on the other hand has the next advantages:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;It&#39;s a more stable project, it&#39;s been alive for much more time and now has the back up of a company trying to make profit out of it. Forgejo&#39;s community and structure is still &lt;a href=&#34;https://codeberg.org/forgejo/meta/issues/187&#34;&gt;evolving to a stable state&lt;/a&gt; though, although it looks promising!&lt;/li&gt; &lt;li&gt;Quicker releases. As Forgejo needs to review and incorporate Gitea&#39;s contributions, it takes longer to do a release.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Being a soft-fork has it&#39;s disadvantages too, for example deciding where to open the issues and pull requests, &lt;a href=&#34;https://codeberg.org/forgejo/meta/issues/114&#34;&gt;they haven&#39;t yet decided which is their policy around this topic&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#authorize-an-ssh-key&#34;&gt;Authorize an SSH key.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Authorize the sender ssh key&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;authorized_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;syncoid&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;state&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;present&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;syncoid_receive_ssh_key&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#create-a-user&#34;&gt;Create a user.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The following snippet creates a user with password login disabled.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Create the syncoid user&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ansible.builtin.user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;syncoid&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;state&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;present&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;password&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;!&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;shell&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/usr/sbin/nologin&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you don&#39;t set a password any user can do &lt;code&gt;su your_user&lt;/code&gt; to set a random password use the next snippet:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Create the syncoid user&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ansible.builtin.user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;syncoid&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;state&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;present&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;password&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;lookup(&#39;password&#39;,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;/dev/null&#39;,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;length=50,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;encrypt=&#39;sha512_crypt&#39;)&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;shell&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/bin/bash&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This won&#39;t pass the idempotence tests as it doesn&#39;t save the password anywhere (&lt;code&gt;/dev/null&lt;/code&gt;) in the controler machine.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#create-an-ssh-key&#34;&gt;Create an ssh key.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Create .ssh directory&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;become&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/root/.ssh&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;state&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;directory&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;700&lt;/span&gt;

&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Create the SSH key to directory&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;become&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;openssh_keypair&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/root/.ssh/id_ed25519&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ed25519&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;register&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ssh&lt;/span&gt;

&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Show public key&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;debug&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ssh.public_key&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#skip-ansible-lint-for-some-tasks&#34;&gt;Skip ansible-lint for some tasks.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Modify permissions&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;chmod -R g-w /home/user&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;skip_ansible_lint&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;sudo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#start-and-enable-a-systemd-service&#34;&gt;Start and enable a systemd service.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Start the service&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;become&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;systemd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;zfs_exporter&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;enabled&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;daemon_reload&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;state&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;started&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#download-an-decompress-a-tar.gz&#34;&gt;Download an decompress a tar.gz.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Unarchive a file that needs to be downloaded (added in 2.0)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ansible.builtin.unarchive&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;https://example.com/example.zip&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;dest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/usr/local/bin&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;remote_src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you want to only extract a file you can use the &lt;code&gt;includes&lt;/code&gt; arg&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Download the zfs exporter&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;become&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ansible.builtin.unarchive&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;https://github.com/pdf/zfs_exporter/releases/download/v{{ zfs_exporter_version }}/zfs_exporter-{{ zfs_exporter_version }}.linux-amd64.tar.gz&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;dest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/usr/local/bin&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;include&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;zfs_exporter&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;remote_src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;yes&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0755&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;But that snippet sometimes fail, you can alternatively download it locally and &lt;code&gt;copy&lt;/code&gt; it:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Test if zfs_exporter binary exists&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;stat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/usr/local/bin/zfs_exporter&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;register&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;zfs_exporter_binary&lt;/span&gt;

&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Install the zfs exporter&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;block&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Download the zfs exporter&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;delegate_to&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;localhost&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ansible.builtin.unarchive&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;https://github.com/pdf/zfs_exporter/releases/download/v{{ zfs_exporter_version }}/zfs_exporter-{{ zfs_exporter_version }}.linux-amd64.tar.gz&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;dest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/tmp/&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;remote_src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;yes&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Upload the zfs exporter to the server&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;become&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;copy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/tmp/zfs_exporter-{{ zfs_exporter_version }}.linux-amd64/zfs_exporter&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;dest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/usr/local/bin&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0755&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;when&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;not zfs_exporter_binary.stat.exists&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#run-command-on-a-working-directory&#34;&gt;Run command on a working directory.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Change the working directory to somedir/ and run the command as db_owner&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ansible.builtin.command&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/usr/bin/make_database.sh db_user db_name&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;become&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;yes&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;become_user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;db_owner&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;chdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;somedir/&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;creates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/path/to/database&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#run-handlers-in-the-middle-of-the-tasks-file&#34;&gt;Run handlers in the middle of the tasks file.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you need handlers to run before the end of the play, add a task to flush them using the &lt;a href=&#34;https://docs.ansible.com/ansible/latest/collections/ansible/builtin/meta_module.html#meta-module&#34;&gt;meta module&lt;/a&gt;, which executes Ansible actions:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;tasks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Some tasks go here&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ansible.builtin.shell&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;...&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Flush handlers&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;meta&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;flush_handlers&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Some other tasks&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ansible.builtin.shell&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The &lt;code&gt;meta: flush_handlers&lt;/code&gt; task triggers any handlers that have been notified at that point in the play.&lt;/p&gt; &lt;p&gt;Once handlers are executed, either automatically after each mentioned section or manually by the &lt;code&gt;flush_handlers meta&lt;/code&gt; task, they can be notified and run again in later sections of the play.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#run-command-idempotently&#34;&gt;Run command idempotently.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Register the runner in gitea&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;become&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;act_runner register --config config.yaml --no-interactive --instance {{ gitea_url }} --token {{ gitea_docker_runner_token }}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;creates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/var/lib/gitea_docker_runner/.runner&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#get-the-correct-architecture-string&#34;&gt;Get the correct architecture string.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you have an &lt;code&gt;amd64&lt;/code&gt; host you&#39;ll get &lt;code&gt;x86_64&lt;/code&gt;, but sometimes you need the &lt;code&gt;amd64&lt;/code&gt; string. On those cases you can use the next snippet:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;deb_architecture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;aarch64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;arm64&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;x86_64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;amd64&lt;/span&gt;

&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;
&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Download the act runner binary&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;become&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;True&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ansible.builtin.get_url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;https://dl.gitea.com/act_runner/act_runner-linux-{{ deb_architecture[ansible_architecture] }}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;dest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/usr/bin/act_runner&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;0755&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#check-the-instances-that-are-going-to-be-affected-by-playbook-run&#34;&gt;Check the instances that are going to be affected by playbook run.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Useful to list the instances of a dynamic inventory&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ansible-inventory&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;aws_ec2.yaml&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--list
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#check-if-variable-is-defined-or-empty&#34;&gt;Check if variable is defined or empty.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;In Ansible playbooks, it is often a good practice to test if a variable exists and what is its value.&lt;/p&gt; &lt;p&gt;Particularity this helps to avoid different “VARIABLE IS NOT DEFINED” errors in Ansible playbooks.&lt;/p&gt; &lt;p&gt;In this context there are several useful tests that you can apply using &lt;a href=&#34;https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html&#34;&gt;Jinja2 filters&lt;/a&gt; in Ansible.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Check if Ansible variable is defined (exists).&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;tasks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;

&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;shell&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;echo &#34;The variable &#39;foo&#39; is defined&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#39;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;when:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;defined&lt;/span&gt;

&lt;span class=&#34;s&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;fail:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;msg=&#34;&lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;The variable &#39;bar&#39; is not defined&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;when&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;bar is undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#check-if-ansible-variable-is-empty&#34;&gt;Check if Ansible variable is empty.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;tasks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;

&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;fail&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;msg=&#34;The variable &#39;bar&#39; is empty&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;when&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;bar|length == 0&lt;/span&gt;

&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;shell&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;echo &#34;The variable &#39;foo&#39; is not empty&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#39;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;when:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;foo|length&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#check-if-ansible-variable-is-defined-and-not-empty&#34;&gt;Check if Ansible variable is defined and not empty.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;tasks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;

&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;shell&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;echo &#34;The variable &#39;foo&#39; is defined and not empty&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;when&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;(foo is defined) and (foo|length &amp;gt; 0)&lt;/span&gt;

&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;fail&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;msg=&#34;The variable &#39;bar&#39; is not defined or empty&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;when&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;(bar is not defined) or (bar|length == 0)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#download-a-file&#34;&gt;Download a file.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Download foo.conf&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ansible.builtin.get_url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;http://example.com/path/file.conf&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;dest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/etc/foo.conf&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;0440&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#ansible-condition-that-uses-a-regexp&#34;&gt;Ansible condition that uses a regexp.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Check if an instance name or hostname matches a regex pattern&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;when&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;inventory_hostname is not match(&#39;molecule-.*&#39;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;fail&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;not&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;molecule&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;instance&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#ansible-lint-doesn&#39;t-find-requirements&#34;&gt;Ansible-lint doesn&#39;t find requirements.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It may be because you&#39;re using &lt;code&gt;requirements.yaml&lt;/code&gt; instead of &lt;code&gt;requirements.yml&lt;/code&gt;. Create a temporal link from one file to the other, run the command and then remove the link.&lt;/p&gt; &lt;p&gt;It will work from then on even if you remove the link. &lt;code&gt;¯\(°_o)/¯&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#run-task-only-once&#34;&gt;Run task only once.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Add &lt;code&gt;run_once: true&lt;/code&gt; on the task definition:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Do a thing on the first host in a group.&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;debug&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;Yay&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;only&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;prints&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;once&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run_once&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#ansible-add-a-sleep&#34;&gt;Ansible add a sleep.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Pause for 5 minutes to build app cache&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ansible.builtin.pause&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;minutes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#ansible-lint-skip-some-rules&#34;&gt;Ansible lint skip some rules.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Add a &lt;code&gt;.ansible-lint-ignore&lt;/code&gt; file with a line per rule to ignore with the syntax &lt;code&gt;path/to/file rule_to_ignore&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;gitea&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/&#34;&gt;Gitea&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce chezmoi.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.chezmoi.io/&#34;&gt;Chezmoi&lt;/a&gt; stores the desired state of your dotfiles in the directory &lt;code&gt;~/.local/share/chezmoi&lt;/code&gt;. When you run &lt;code&gt;chezmoi apply&lt;/code&gt;, &lt;code&gt;chezmoi&lt;/code&gt; calculates the desired contents for each of your dotfiles and then makes the minimum changes required to make your dotfiles match your desired state.&lt;/p&gt; &lt;p&gt;What I like:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Supports &lt;code&gt;pass&lt;/code&gt; to retrieve credentials.&lt;/li&gt; &lt;li&gt;Popular&lt;/li&gt; &lt;li&gt;Can remove directories on &lt;code&gt;apply&lt;/code&gt;&lt;/li&gt; &lt;li&gt;It has a &lt;code&gt;diff&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.chezmoi.io/user-guide/include-files-from-elsewhere/&#34;&gt;It can include dotfiles from an URL&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.chezmoi.io/user-guide/encryption/gpg/&#34;&gt;Encrypt files with gpg&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/alker0/chezmoi.vim&#34;&gt;There&#39;s a vim plugin&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Actively maintained&lt;/li&gt; &lt;li&gt;Good documentation&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;What I don&#39;t like:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Go templates, although &lt;a href=&#34;https://www.chezmoi.io/user-guide/templating/#creating-a-template-file&#34;&gt;it supports autotemplating&lt;/a&gt; and it&#39;s &lt;a href=&#34;https://www.chezmoi.io/user-guide/templating/#template-variables&#34;&gt;well explained&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Written in Go&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;In the article you can also find:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/chezmoi/#installation&#34;&gt;How to install it&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/chezmoi/#basic-usage&#34;&gt;How to use it&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/chezmoi/#install-a-binary-from-an-external-url&#34;&gt;How to install a binary from an external url&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Update the project url of helm-secrets.&lt;/p&gt; &lt;p&gt;From &lt;a href=&#34;https://github.com/futuresimple/helm-secrets&#34;&gt;https://github.com/futuresimple/helm-secrets&lt;/a&gt; to &lt;a href=&#34;https://github.com/jkroepke/helm-secrets&#34;&gt;https://github.com/jkroepke/helm-secrets&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#disable-the-regular-login-use-only-oauth&#34;&gt;Disable the regular login, use only Oauth.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You need to add a file inside your &lt;a href=&#34;https://docs.gitea.io/en-us/customizing-gitea/&#34;&gt;&lt;code&gt;custom&lt;/code&gt; directory&lt;/a&gt;. The file is too big to add in this digest, please access the article to get it.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#configure-it-with-terraform&#34;&gt;Configure it with terraform.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Gitea can be configured through terraform too. There is an &lt;a href=&#34;https://gitea.com/gitea/terraform-provider-gitea/src/branch/main&#34;&gt;official provider&lt;/a&gt; that doesn&#39;t work, there&#39;s a &lt;a href=&#34;https://registry.terraform.io/providers/Lerentis/gitea/latest/docs&#34;&gt;fork that does though&lt;/a&gt;. Sadly it doesn&#39;t yet support configuring Oauth Authentication sources. Be careful &lt;a href=&#34;https://registry.terraform.io/providers/Lerentis/gitea/latest/docs/resources/oauth2_app&#34;&gt;&lt;code&gt;gitea_oauth2_app&lt;/code&gt;&lt;/a&gt; looks to be the right resource to do that, but instead it configures Gitea to be the Oauth provider, not a consumer.&lt;/p&gt; &lt;p&gt;In the article you can find how to configure and use it to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#create-an-organization&#34;&gt;Create an organization&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#create-an-admin-user-through-the-command-line&#34;&gt;Create an admin user through the command line.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;gitea&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--config&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/gitea/app.ini&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;admin&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;user&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;create&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--admin&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--username&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;user_name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--password&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;password&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--email&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;email
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Or you can change &lt;a href=&#34;https://discourse.gitea.io/t/how-to-change-gitea-admin-password-from-the-command-terminal-line/1930&#34;&gt;the admin&#39;s password&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;gitea&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--config&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/gitea/app.ini&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;admin&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;user&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;change-password&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-u&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;username&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;password
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; feat(gtd): Introduce Getting things done&lt;/p&gt; &lt;p&gt;First summary of David Allen&#39;s book Getting things done. It includes:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#theory-principles&#34;&gt;Theory principles&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#managing-commitments&#34;&gt;Managing commitments&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#managing-stuff&#34;&gt;Managing stuff&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#managing-actions&#34;&gt;Managing actions&lt;/a&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#workflow-steps&#34;&gt;Workflow steps&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#capture&#34;&gt;Capture what has our attention.&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#clarify-and-organize&#34;&gt;Clarify what each item means and what to do about it.&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#clarify-and-organize&#34;&gt;Organize the results.&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#reflect&#34;&gt;Reflect on the options.&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#engage&#34;&gt;Engage the chosen options.&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#setting-up-the-system&#34;&gt;Setting up the system&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#setting-up-the-space&#34;&gt;Setting up the space&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gtd/#setting-up-your-filing-system&#34;&gt;Setting up your filing system&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#configure-gitea-actions&#34;&gt;Gitea actions overview.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;We&#39;ve been using &lt;a href=&#34;https://lyz-code.github.io/blue-book/drone/&#34;&gt;Drone&lt;/a&gt; as CI runner for some years now as Gitea didn&#39;t have their native runner. On &lt;a href=&#34;https://blog.gitea.io/2023/03/gitea-1.19.0-is-released/&#34;&gt;Mar 20, 2023&lt;/a&gt; however Gitea released the version 1.19.0 which promoted to stable the Gitea Actions which is a built-in CI system like GitHub Actions. With Gitea Actions, you can reuse your familiar workflows and Github Actions in your self-hosted Gitea instance. While it is not currently fully compatible with GitHub Actions, they intend to become as compatible as possible in future versions. The typical procedure is as follows:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Register a runner (at the moment, act runners are the only option). This can be done on the following scopes:&lt;/li&gt; &lt;li&gt;site-wide (by site admins)&lt;/li&gt; &lt;li&gt;organization-wide (by organization owners)&lt;/li&gt; &lt;li&gt;repository-wide (by repository owners)&lt;/li&gt; &lt;li&gt;Create workflow files under &lt;code&gt;.gitea/workflows/&amp;lt;workflow name&amp;gt;.yaml&lt;/code&gt; or &lt;code&gt;.github/workflows/&amp;lt;workflow name&amp;gt;.yaml&lt;/code&gt;. The syntax is the same as &lt;a href=&#34;https://docs.github.com/en/actions&#34;&gt;the GitHub workflow syntax&lt;/a&gt; where supported.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Gitea Actions advantages are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Uses the same pipeline syntax as Github Actions, so it&#39;s easier to use for new developers&lt;/li&gt; &lt;li&gt;You can reuse existent Github actions.&lt;/li&gt; &lt;li&gt;Migration from Github repositories to Gitea is easier.&lt;/li&gt; &lt;li&gt;You see the results of the workflows in the same gitea webpage, which is much cleaner than needing to go to drone&lt;/li&gt; &lt;li&gt;Define the secrets in the repository configuration.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Drone advantages are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;They have the promote event. Not critical as we can use other git events such as creating a tag.&lt;/li&gt; &lt;li&gt;They can be run as a service by default. The gitea runners will need some work to run on instance restart.&lt;/li&gt; &lt;li&gt;Has support for &lt;a href=&#34;https://docs.drone.io/quickstart/kubernetes/&#34;&gt;running kubernetes pipelines&lt;/a&gt;. Gitea actions doesn&#39;t yet support this&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#setup-gitea-actions&#34;&gt;Setup Gitea actions.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You need a Gitea instance with a version of 1.19.0 or higher. Actions are disabled by default (as they are still an feature-in-progress), so you need to add the following to the configuration file to enable it:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[actions]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;ENABLED&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Even if you enable at configuration level you need to manually enable the actions on each repository &lt;a href=&#34;https://github.com/go-gitea/gitea/issues/23724&#34;&gt;until this issue is solved&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;So far there is &lt;a href=&#34;https://gitea.com/gitea/act_runner&#34;&gt;only one possible runner&lt;/a&gt; which is based on docker and &lt;a href=&#34;https://github.com/nektos/act&#34;&gt;&lt;code&gt;act&lt;/code&gt;&lt;/a&gt;. Currently, the only way to install act runner is by compiling it yourself, or by using one of the &lt;a href=&#34;http://dl.gitea.com/act_runner&#34;&gt;pre-built binaries&lt;/a&gt;. There is no Docker image or other type of package management yet. At the moment, act runner should be run from the command line. Of course, you can also wrap this binary in something like a system service, supervisord, or Docker container.&lt;/p&gt; &lt;p&gt;Before running a runner, you should first register it to your Gitea instance using the following command:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;./act_runner&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;register&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--no-interactive&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--instance&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;instance&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--token&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;token&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;There are two arguments required, &lt;code&gt;instance&lt;/code&gt; and &lt;code&gt;token&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;&lt;code&gt;instance&lt;/code&gt; refers to the address of your Gitea instance, like &lt;code&gt;http://192.168.8.8:3000&lt;/code&gt;. The runner and job containers (which are started by the runner to execute jobs) will connect to this address. This means that it could be different from the &lt;code&gt;ROOT_URL&lt;/code&gt; of your Gitea instance, which is configured for web access. It is always a bad idea to use a loopback address such as &lt;code&gt;127.0.0.1&lt;/code&gt; or &lt;code&gt;localhost&lt;/code&gt;, as we will discuss later. If you are unsure which address to use, the LAN address is usually the right choice.&lt;/p&gt; &lt;p&gt;&lt;code&gt;token&lt;/code&gt; is used for authentication and identification, such as &lt;code&gt;P2U1U0oB4XaRCi8azcngmPCLbRpUGapalhmddh23&lt;/code&gt;. It is one-time use only and cannot be used to register multiple runners. You can obtain tokens from &lt;code&gt;your_gitea.com/admin/runners&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;After registering, a new file named &lt;code&gt;.runner&lt;/code&gt; will appear in the current directory. This file stores the registration information. Please do not edit it manually. If this file is missing or corrupted, you can simply remove it and register again.&lt;/p&gt; &lt;p&gt;Finally, it’s time to start the runner.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;./act_runner&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;daemon
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#use-the-gitea-actions&#34;&gt;Use the gitea actions.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Even if Actions is enabled for the Gitea instance, repositories &lt;a href=&#34;https://github.com/go-gitea/gitea/issues/23724&#34;&gt;still disable Actions by default&lt;/a&gt;. Enable it on the settings page of your repository.&lt;/p&gt; &lt;p&gt;You will need to study &lt;a href=&#34;https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions&#34;&gt;the workflow syntax&lt;/a&gt; for Actions and write the workflow files you want.&lt;/p&gt; &lt;p&gt;However, we can just start from a simple demo:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Gitea Actions Demo&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;run-name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;${{ gitea.actor }} is testing out Gitea Actions&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;push&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;jobs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;Explore-Gitea-Actions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;runs-on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ubuntu-latest&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;steps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;echo &#34;The job was automatically triggered by a ${{ gitea.event_name }} event.&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;echo &#34;This job is now running on a ${{ runner.os }} server hosted by Gitea!&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;echo &#34;The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}.&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Check out repository code&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;actions/checkout@v3&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;echo &#34;The ${{ gitea.repository }} repository has been cloned to the runner.&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;echo &#34;The workflow is now ready to test your code on the runner.&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;List files in the repository&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;ls ${{ gitea.workspace }}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;echo &#34;This job&#39;s status is ${{ gitea.status }}.&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can upload it as a file with the extension &lt;code&gt;.yaml&lt;/code&gt; in the directory &lt;code&gt;.gitea/workflows/&lt;/code&gt; or &lt;code&gt;.github/workflows&lt;/code&gt; of the repository, for example &lt;code&gt;.gitea/workflows/demo.yaml&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;You may be aware that there are tens of thousands of &lt;a href=&#34;https://github.com/marketplace?type=actions&#34;&gt;marketplace actions in GitHub&lt;/a&gt;. However, when you write &lt;code&gt;uses: actions/checkout@v3&lt;/code&gt;, it actually downloads the scripts from gitea.com/actions/checkout by default (not GitHub). This is a mirror of github.com/actions/checkout, but it’s impossible to mirror all of them. That’s why you may encounter failures when trying to use some actions that haven’t been mirrored.&lt;/p&gt; &lt;p&gt;The good news is that you can specify the URL prefix to use actions from anywhere. This is an extra syntax in Gitea Actions. For example:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;uses: https://github.com/xxx/xxx@xxx&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;uses: https://gitea.com/xxx/xxx@xxx&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;uses: http://your_gitea_instance.com/xxx@xxx&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Be careful, the &lt;code&gt;https://&lt;/code&gt; or &lt;code&gt;http://&lt;/code&gt; prefix is necessary!&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Import organisations into terraform.&lt;/p&gt; &lt;p&gt;To import organisations and teams you need to use their &lt;code&gt;ID&lt;/code&gt;. You can see the ID of the organisations in the Administration panel. To get the Teams ID you need to use the API. Go to &lt;a href=&#34;https://your.gitea.com/api/swagger#/organization/orgListTeams&#34;&gt;https://your.gitea.com/api/swagger#/organization/orgListTeams&lt;/a&gt; and enter the organisation name.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Give some tip to deal with big diffs.&lt;/p&gt; &lt;p&gt;Sometimes the &lt;code&gt;diff&lt;/code&gt; is too big and you need to work with it chuck by chunk. For each change you can either:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;chezmoi add &amp;lt;target&amp;gt;&lt;/code&gt; if you want to keep the changes you&#39;ve manually made to the files that match the &lt;code&gt;&amp;lt;target&amp;gt;&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;&lt;code&gt;chezmoi apply &amp;lt;target&amp;gt;&lt;/code&gt; if you want to apply the changes that chezmoi proposes for the &lt;code&gt;&amp;lt;target&amp;gt;&lt;/code&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Here &lt;code&gt;&amp;lt;target&amp;gt;&lt;/code&gt; is any directory or file listed in the &lt;code&gt;diff&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add systemd service for the actions runner.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[Unit]
Description=Gitea Actions Runner
After=network.target

[Service]
WorkingDirectory=/var/gitea/gitea/act_runner/main
ExecStart=/var/gitea/gitea/act_runner/main/act_runner-main-linux-amd64 daemon

[Install]
WantedBy=default.target
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#tweak-the-runner-image&#34;&gt;Tweak the runner image.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The &lt;a href=&#34;https://docs.gitea.com/next/usage/actions/act-runner/#labels&#34;&gt;gitea runner&lt;/a&gt; uses the &lt;code&gt;node:16-bullseye&lt;/code&gt; image by default, in that image &lt;a href=&#34;https://itsthejoker.github.io/gitea_actions_and_python/&#34;&gt;the &lt;code&gt;setup-python&lt;/code&gt; action doesn&#39;t work&lt;/a&gt;. You can tweak the docker image that the runner runs by editing the &lt;code&gt;.runner&lt;/code&gt; file that is in the directory where you registered the runner (probably close to the &lt;code&gt;act_runner&lt;/code&gt; executable).&lt;/p&gt; &lt;p&gt;If you open that up, you’ll see that there is a section called labels, and it (most likely) looks like this:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;&#34;labels&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;ubuntu-latest:docker://node:16-bullseye&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;ubuntu-22.04:docker://node:16-bullseye&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;ubuntu-20.04:docker://node:16-bullseye&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;ubuntu-18.04:docker://node:16-buster&#34;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can specify any other docker image. Adding new labels doesn&#39;t work yet.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce molecule.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/ansible-community/molecule&#34;&gt;Molecule&lt;/a&gt; is a testing tool for ansible roles.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/ansible-community/molecule&#34;&gt;Source&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://molecule.rtfd.io/&#34;&gt;Docs&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/molecule/#ci-configuration&#34;&gt;CI configuration.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Since gitea supports github actions you can use the &lt;code&gt;setup-molecule&lt;/code&gt; and &lt;code&gt;setup-lint&lt;/code&gt; actions. For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Molecule&lt;/span&gt;

&lt;span class=&#34;s&#34;&gt;&#34;on&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;pull_request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;env&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;PY_COLORS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;1&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ANSIBLE_FORCE_COLOR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;1&#34;&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;jobs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;lint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Lint&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;runs-on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ubuntu-latest&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;steps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Checkout the codebase&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;actions/checkout@v3&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Setup Lint&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;bec-galaxy/setup-lint@{Version}&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Run Lint tests&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ansible-lint&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;molecule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Molecule&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;runs-on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ubuntu-latest&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;needs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;lint&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;steps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Checkout the codebase&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;actions/checkout@v3&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Setup Molecule&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;bec-galaxy/setup-molecule@{Version}&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Run Molecule tests&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;molecule test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/bec-galaxy/setup-molecule/blob/main/action.yml&#34;&gt;That action&lt;/a&gt; installs the latest version of the packages, if you need to check a specific version of the packages you may want to create your own step or your own action.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/molecule/#to-v5.0.0&#34;&gt;Upgrade to v5.0.0.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;They&#39;ve removed the &lt;code&gt;lint&lt;/code&gt; command, the reason behind is that there are two different testing methods which are expected to be run in very different ways. Linting should be run per entire repository. Molecule executions are per scenario and one project can have even &amp;gt;100 scenarios. Running lint on each of them would not only slowdown but also increase the maintenance burden on linter configuration and the way is called.&lt;/p&gt; &lt;p&gt;They recommend users to run &lt;code&gt;ansible-lint&lt;/code&gt; using &lt;code&gt;pre-commit&lt;/code&gt; with or without `tox. That gives much better control over how/when it is updated.&lt;/p&gt; &lt;p&gt;You can see an example on how to do this in the &lt;a href=&#34;#ci-configuration&#34;&gt;CI configuration section&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Configure the gitea actions.&lt;/p&gt; &lt;p&gt;So far there is &lt;a href=&#34;https://gitea.com/gitea/act_runner&#34;&gt;only one possible runner&lt;/a&gt; which is based on docker and &lt;a href=&#34;https://github.com/nektos/act&#34;&gt;&lt;code&gt;act&lt;/code&gt;&lt;/a&gt;. Currently, the only way to install act runner is by compiling it yourself, or by using one of the &lt;a href=&#34;https://dl.gitea.com/act_runner&#34;&gt;pre-built binaries&lt;/a&gt;. There is no Docker image or other type of package management yet. At the moment, act runner should be run from the command line. Of course, you can also wrap this binary in something like a system service, supervisord, or Docker container.&lt;/p&gt; &lt;p&gt;You can create the default configuration of the runner with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;./act_runner&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;generate-config&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;config.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can tweak there for example the &lt;code&gt;capacity&lt;/code&gt; so you are able to run more than one workflow in parallel.&lt;/p&gt; &lt;p&gt;Before running a runner, you should first register it to your Gitea instance using the following command:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;./act_runner&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;register&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--config&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;config.yaml&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--no-interactive&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--instance&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;instance&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--token&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;token&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Finally, it’s time to start the runner.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;./act_runner&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--config&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;config.yaml&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;daemon
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you want to create your own act docker, you can start with this dockerfile:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;node:16-bullseye&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;LABEL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;prune&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mkdir&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/root/.aws
&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;files/config&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/root/.aws/config
&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;files/credentials&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/root/.aws/credentials

&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-y&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;python3&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;python3-pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;python3-venv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;screen&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;vim&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;python3&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-m&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--upgrade&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-rf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/apt/lists/*

&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;molecule&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;5&lt;/span&gt;.0.1&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ansible&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8&lt;/span&gt;.0.0&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;ansible-lint&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;yamllint&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;molecule-plugins&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;ec2,docker,vagrant&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;boto3&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;botocore&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;testinfra&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;pytest

&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wget&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://download.docker.com/linux/static/stable/x86_64/docker-24.0.2.tgz&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tar&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;xvzf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker-24.0.2.tgz&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker/*&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/usr/bin&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker-*
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;It&#39;s prepared for:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Working within an AWS environment&lt;/li&gt; &lt;li&gt;Run Ansible and molecule&lt;/li&gt; &lt;li&gt;Build dockers&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#build-a-docker-within-a-gitea-action&#34;&gt;Build a docker within a gitea action.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Assuming you&#39;re using the custom gitea_runner docker proposed above you can build and upload a docker to a registry with this action:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Publish Docker image&lt;/span&gt;

&lt;span class=&#34;s&#34;&gt;&#34;on&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;push&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;jobs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;build-and-push&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;runs-on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ubuntu-latest&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;steps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Checkout code&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;https://github.com/actions/checkout@v3&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Login to Docker Registry&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;https://github.com/docker/login-action@v2&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;registry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;my_registry.org&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;username&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;${{ secrets.REGISTRY_USERNAME }}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;password&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;${{ secrets.REGISTRY_PASSWORD }}&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Set up QEMU&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;https://github.com/docker/setup-qemu-action@v2&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Set up Docker Buildx&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;https://github.com/docker/setup-buildx-action@v2&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Extract metadata (tags, labels) for Docker&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;meta&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;https://github.com/docker/metadata-action@v4&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;my_registry.org/the_name_of_the_docker_to_build&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Build and push&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;docker/build-push-action@v2&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;.&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;platforms&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;linux/amd64,linux/arm64&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;push&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cache-from&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;type=registry,ref=my_registry.org/the_name_of_the_docker_to_build:buildcache&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cache-to&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;type=registry,ref=my_registry.org/the_name_of_the_docker_to_build:buildcache,mode=max&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;${{ steps.meta.outputs.tags }}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;${{ steps.meta.outputs.labels }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;It uses a pair of nice features:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Multi-arch builds&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://docs.docker.com/build/ci/github-actions/cache/&#34;&gt;Cache&lt;/a&gt; to speed up the builds&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;As it reacts to all events it will build and push:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;A tag with the branch name on each push to that branch&lt;/li&gt; &lt;li&gt;A tag with the tag on tag push&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#bump-the-version-of-a-repository-on-commits-on-master&#34;&gt;Bump the version of a repository on commits on master.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Create a SSH key for the CI to send commits to protected branches.&lt;/li&gt; &lt;li&gt;Upload the private key to a repo or organization secret called &lt;code&gt;DEPLOY_SSH_KEY&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;Upload the public key to the repo configuration deploy keys&lt;/li&gt; &lt;li&gt; &lt;p&gt;Create the &lt;code&gt;bump.yaml&lt;/code&gt; file with the next contents:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Bump version&lt;/span&gt;

&lt;span class=&#34;s&#34;&gt;&#34;on&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;push&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;branches&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;main&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;jobs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;bump_version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;!startsWith(github.event.head_commit.message,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;bump:&#39;)&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;runs-on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ubuntu-latest&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;Bump&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;and&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;create&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;changelog&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;steps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Check out&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;actions/checkout@v3&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;fetch-depth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Fetch all history&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Configure SSH&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;echo &#34;${{ secrets.DEPLOY_SSH_KEY }}&#34; &amp;gt; ~/.ssh/deploy_key&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;chmod 600 ~/.ssh/deploy_key&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;dos2unix ~/.ssh/deploy_key&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;ssh-agent -a $SSH_AUTH_SOCK &amp;gt; /dev/null&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;ssh-add ~/.ssh/deploy_key&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Bump the version&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;cz bump --changelog --no-verify&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Push changes&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;git remote add ssh git@gitea-production.cloud.icij.org:templates/ansible-role.git&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;git pull ssh main&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;git push ssh main&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;git push ssh --tags&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;It assumes that you have &lt;code&gt;cz&lt;/code&gt; (commitizen) and &lt;code&gt;dos2unix&lt;/code&gt; installed in your runner.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#skip-gitea-actions-job-on-changes-of-some-files&#34;&gt;Skip gitea actions job on changes of some files.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;There are some expensive CI pipelines that don&#39;t need to be run for example if you changed a line in the &lt;code&gt;README.md&lt;/code&gt;, to skip a pipeline on changes of certain files you can use the &lt;code&gt;paths-ignore&lt;/code&gt; directive:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Ansible Testing&lt;/span&gt;

&lt;span class=&#34;s&#34;&gt;&#34;on&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;push&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;paths-ignore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;meta/**&#39;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Makefile&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;README.md&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;renovate.json&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;CHANGELOG.md&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;.cz.toml&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;.gitea/workflows/**&#39;&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;jobs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;test&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Test&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;runs-on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ubuntu-latest&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;steps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The only downside is that if you set this pipeline as required in the branch protection, the merge button will look yellow instead of green when the pipeline is skipped.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/molecule/#molecule-doesn&#39;t-find-the-molecule.yaml-file&#34;&gt;Molecule doesn&#39;t find the &lt;code&gt;molecule.yaml&lt;/code&gt; file.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This is expected default behavior since Molecule searches for scenarios using the &lt;code&gt;molecule/*/molecule.yml&lt;/code&gt; glob. But if you would like to change the suffix to yaml, you can do that if you set the &lt;code&gt;MOLECULE_GLOB&lt;/code&gt; environment variable like this:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;MOLECULE_GLOB&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;molecule/*/molecule.yaml&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#using-paths-filter-custom-action&#34;&gt;Using &lt;code&gt;paths-filter&lt;/code&gt; custom action to skip job actions.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jobs:
  test:
    if: &#34;!startsWith(github.event.head_commit.message, &#39;bump:&#39;)&#34;
    name: Test
    runs-on: ubuntu-latest
    steps:
      - name: Checkout the codebase
        uses: https://github.com/actions/checkout@v3

      - name: Check if we need to run the molecule tests
        uses: https://github.com/dorny/paths-filter@v2
        id: filter
        with:
          filters: |
            molecule:
              - &#39;defaults/**&#39;
              - &#39;tasks/**&#39;
              - &#39;handlers/**&#39;
              - &#39;tasks/**&#39;
              - &#39;templates/**&#39;
              - &#39;molecule/**&#39;
              - &#39;requirements.yaml&#39;
              - &#39;.github/workflows/tests.yaml&#39;

      - name: Run Molecule tests
        if: steps.filter.outputs.molecule == &#39;true&#39;
        run: make molecule
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can find more examples on how to use &lt;code&gt;paths-filter&lt;/code&gt; &lt;a href=&#34;https://github.com/dorny/paths-filter#examples&#34;&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/molecule/#get-variables-from-the-environment&#34;&gt;Get variables from the environment.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can configure your &lt;code&gt;molecule.yaml&lt;/code&gt; file to read variables from the environment with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;provisioner&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ansible&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;inventory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;group_vars&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;all&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;my_secret&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;${MY_SECRET}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;It&#39;s useful to have a task that checks if this secret exists:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Verify that the secret is set&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;fail&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;Please&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;my_secret:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;MY_SECRET=$(pass&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;show&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;my_secret)&#39;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run_once&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;when&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;my_secret == None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;In the CI you can set it as a secret in the repository.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#run-jobs-if-other-jobs-failed&#34;&gt;Run jobs if other jobs failed.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This is useful to send notifications if any of the jobs failed.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/go-gitea/gitea/issues/23725&#34;&gt;Right now&lt;/a&gt; you can&#39;t run a job if other jobs fail, all you can do is add a last step on each workflow to do the notification on failure:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Send mail&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;failure()&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;https://github.com/dawidd6/action-send-mail@v3&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;to&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;${{ secrets.MAIL_TO }}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;from&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Gitea &amp;lt;gitea@hostname&amp;gt;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;${{ gitea.repository }} ${{gitea.workflow}} ${{ job.status }}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;priority&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;high&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;convert_markdown&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;html_body&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;### Job ${{ job.status }}&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;${{ github.repository }}: [${{ github.ref }}@${{ github.sha }}](${{ github.server_url }}/${{ github.repository }}/actions)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;helmfile&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/dotdrop/&#34;&gt;Helmfile&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/helmfile/#yaml-templates-in-go-templates&#34;&gt;Troubleshoot Yaml templates in go templates.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you are using a &lt;code&gt;values.yaml.gotmpl&lt;/code&gt; file you won&#39;t be able to use &lt;code&gt;{{ whatever }}&lt;/code&gt;. The solution is to extract that part to a yaml file and include it in the go template. For example:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;values.yaml.gotmpl&lt;/code&gt;:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;metrics:
serviceMonitor:
  enabled: true
  annotations:
  additionalLabels:
    release: prometheus-operator

{{ readFile &#34;prometheus_rules.yaml&#34; }}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;prometheus_rules.yaml&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;prometheusRule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;enabled&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;additionalLabels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;release&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;prometheus-operator&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;VeleroBackupPartialFailures&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Velero backup {{ $labels.schedule }} has {{ $value | humanizePercentage }} partialy failed backups.&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;increase(velero_backup_partial_failure_total{schedule!=&#34;&#34;}[1h]) &amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;15m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce dotdrop.&lt;/p&gt; &lt;p&gt;The main idea of &lt;a href=&#34;https://deadc0de.re/dotdrop/&#34;&gt;Dotdrop&lt;/a&gt;is to have the ability to store each dotfile only once and deploy them with a different content on different hosts/setups. To achieve this, it uses a templating engine that allows to specify, during the dotfile installation with dotdrop, based on a selected profile, how (with what content) each dotfile will be installed.&lt;/p&gt; &lt;p&gt;What I like:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Popular&lt;/li&gt; &lt;li&gt;Actively maintained&lt;/li&gt; &lt;li&gt;Written in Python&lt;/li&gt; &lt;li&gt;Uses jinja2&lt;/li&gt; &lt;li&gt;Has a nice to read config file&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;What I don&#39;t like:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://dotdrop.readthedocs.io/en/latest/usage/#update-dotfiles&#34;&gt;Updating dotfiles doesn&#39;t look as smooth as with chezmoi&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Uses &lt;code&gt;{{@@ @@}}&lt;/code&gt; instead of &lt;code&gt;{{ }}&lt;/code&gt; :S&lt;/li&gt; &lt;li&gt;Doesn&#39;t support &lt;code&gt;pass&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;Not easy way to edit the files.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;terraform&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/terraform/&#34;&gt;Terraform&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: How to install it.&lt;/p&gt; &lt;p&gt;Go to the &lt;a href=&#34;https://github.com/hashicorp/terraform/releases&#34;&gt;releases page&lt;/a&gt;, download the latest release, decompress it and add it to your &lt;code&gt;$PATH&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/terraform/#sensitive-information&#34;&gt;How to store sensitive information in terraform.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;One of the most common questions we get about using Terraform to manage infrastructure as code is how to handle secrets such as passwords, API keys, and other sensitive data.&lt;/p&gt; &lt;p&gt;In the article you&#39;ll find how to store your sensitive data in:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/terraform/#sensitive-information-in-the-terraform-state&#34;&gt;The Terraform state&lt;/a&gt;: Using the state backend encryption&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/terraform/#sensitive-information-in-the-terraform-source-code&#34;&gt;The Terraform source code&lt;/a&gt;: Using&lt;code&gt;sops&lt;/code&gt; and &lt;code&gt;gpg&lt;/code&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/terraform/#create-a-list-of-resources-based-on-a-list-of-strings&#34;&gt;Create a list of resources based on a list of strings.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;variable&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&#34;subnet_ids&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;kr&#34;&gt;resource&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;&#34;aws_instance&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&#34;server&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;  # Create one instance for each subnet&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;length&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;var.subnet_ids&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;ami&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;ami-a1b2c3d4&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;instance_type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;t2.micro&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;subnet_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;var.subnet_ids[count.index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;tags&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;Name&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Server ${count.index}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you want to use this generated list on another resource extracting for example the id you can use&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;aws_instance.server&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;id&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;dotfiles&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/dotfiles/&#34;&gt;Dotfiles&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce dotfiles.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://wiki.archlinux.org/title/Dotfiles&#34;&gt;User-specific application configuration is traditionally stored in so called dotfiles&lt;/a&gt; (files whose filename starts with a dot). It is common practice to track dotfiles with a version control system such as Git to keep track of changes and synchronize dotfiles across various hosts. There are various approaches to managing your dotfiles (e.g. directly tracking dotfiles in the home directory v.s. storing them in a subdirectory and symlinking/copying/generating files with a shell script or a dedicated tool).&lt;/p&gt; &lt;p&gt;Note: this is not meant to configure files that are outside your home directory, use Ansible for that use case.&lt;/p&gt; &lt;p&gt;You can find different ways to track your dotfiles:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/dotfiles/#tracking-dotfiles-directly-with-git&#34;&gt;Tracking dotfiles directly with Git&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/dotfiles/#using-Ansible-to-manage-the-dotfiles&#34;&gt;Using Ansible to manage the dotfiles&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/dotfiles/#tools&#34;&gt;Using dotfiles specific tools, and an analysis of the state of the art&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;infrastructure-solutions&#34;&gt;Infrastructure Solutions&lt;/h3&gt; &lt;h4 id=&#34;velero&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/velero/&#34;&gt;Velero&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce velero.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://velero.io/&#34;&gt;Velero&lt;/a&gt; is an open source tool to safely backup and restore, perform disaster recovery, and migrate Kubernetes cluster resources and persistent volumes.&lt;/p&gt; &lt;p&gt;In the article you&#39;ll also find how to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/velero/#client-installation&#34;&gt;Install the client&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/velero/#server-configuration&#34;&gt;Configure the server&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/velero/#monitorization&#34;&gt;Monitor it with Prometheus&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/velero/#restore-backups&#34;&gt;Restore backups&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;And an &lt;a href=&#34;https://lyz-code.github.io/blue-book/velero/#overview-of-velero&#34;&gt;overview of the whole application infrastructure&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/velero/#create-a-backup&#34;&gt;Create a backup.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you already have schedules select the one you want to use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;velero&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;schedules&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then create the backup with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;velero&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;backup&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;create&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--from-schedule&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;selected-schedule
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can see the other options to create backups in &lt;code&gt;velero backup create --help&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;aws-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubectl/kubectl_installation/&#34;&gt;AWS Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Recommend to use distro repos when installing.&lt;/p&gt; &lt;p&gt;It&#39;s available now in debian&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/aws/aws/#stop-an-ec2-instance&#34;&gt;Stop an EC2 instance.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;aws&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ec2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;stop-instances&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--instance-ids&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;i-xxxxxxxx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/aws_snippets/#get-ec2-metadata-from-within-the-instance&#34;&gt;Get EC2 metadata from within the instance.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The quickest way to fetch or retrieve EC2 instance metadata from within a running EC2 instance is to log in and run the command:&lt;/p&gt; &lt;p&gt;Fetch metadata from IPv4:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;http://169.254.169.254/latest/dynamic/instance-identity/document
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can also download the &lt;code&gt;ec2-metadata&lt;/code&gt; tool to get the info:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;wget&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;http://s3.amazonaws.com/ec2metadata/ec2-metadata

chmod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;+x&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ec2-metadata

./ec2-metadata&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--all
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: [Remove the lock screen in ubuntu.](../aws_snippets.md#invalidate-a-cloudfront-distribution&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;aws-cloudfront-create-invalidation---paths-&lt;span class=&#34;s2&#34;&gt;&#34;/pages/about&#34;&lt;/span&gt;---distribution-id-my-distribution-id
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;feat(bash_snippets)&lt;/p&gt; &lt;pre&gt;&lt;code&gt;Create the `/usr/share/glib-2.0/schemas/90_ubuntu-settings.gschema.override` file with the next content:

```ini
[org.gnome.desktop.screensaver]
lock-enabled = false
[org.gnome.settings-daemon.plugins.power]
idle-dim = false
```

Then reload the schemas with:

```bash
sudo glib-compile-schemas /usr/share/glib-2.0/schemas/
```
&lt;/code&gt;&lt;/pre&gt; &lt;h4 id=&#34;kubectl-commands&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubectl/kubectl_commands/&#34;&gt;Kubectl Commands&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubectl/kubectl_commands/#show-the-remaining-space-of-a-persistent-volume-claim&#34;&gt;Show the remaining space of a persistent volume claim.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Either look it in Prometheus or run in the pod that has the PVC mounted:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;namespace&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;pod-name&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;df&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-ah
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You may need to use &lt;code&gt;kubectl get pod &amp;lt;pod-name&amp;gt; -o yaml&lt;/code&gt; to know what volume is mounted where.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubectl/kubectl_commands/#run-a-pod-in-a-defined-node&#34;&gt;Run a pod in a defined node.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Get the node hostnames with &lt;code&gt;kubectl get nodes&lt;/code&gt;, then override the node with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;run&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mypod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--image&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ubuntu:18.04&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--overrides&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;{&#34;apiVersion&#34;: &#34;v1&#34;, &#34;spec&#34;: {&#34;nodeSelector&#34;: { &#34;kubernetes.io/hostname&#34;: &#34;my-node.internal&#34; }}}&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--command&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sleep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;100000000000000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;tools&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes_tools/&#34;&gt;Tools&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes_tools/#tried&#34;&gt;Recommend rke2 over k3s.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;A friend told me that it works better.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;continuous-integration&#34;&gt;Continuous Integration&lt;/h3&gt; &lt;h4 id=&#34;mypy&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/mypy/&#34;&gt;Mypy&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/mypy/#module-&#34; title=&#39;typing&#34;-has-no-attribute-&#34;annotated&#39;&gt;Module &#34;typing&#34; has no attribute &#34;Annotated&#34;.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This one happens only because &lt;code&gt;annotated&lt;/code&gt; is not available in python &amp;lt; 3.9.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;try:
    # mypy is complaining that it can&#39;t import it, but it&#39;s solved below
    from typing import Annotated # type: ignore
except ImportError:
    from typing_extensions import Annotated
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;drone&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/drone/&#34;&gt;Drone&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/drone/#create-the-administrators&#34;&gt;Create the administrators.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;When you configure the Drone server you can create the initial administrative account by passing the below environment variable, which defines the account username (e.g. github handle) and admin flag set to true.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;DRONE_USER_CREATE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;username:octocat,admin:true
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you need to grant the primary administrative role to an existing user, you can provide an existing username. Drone will update the account and grant administrator role on server restart.&lt;/p&gt; &lt;p&gt;You can create administrator accounts using the command line tools. Please see the command line tools documentation for installation instructions.&lt;/p&gt; &lt;p&gt;Create a new administrator account:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;drone&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;user&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;add&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;octocat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--admin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Or grant the administrator role to existing accounts:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;drone&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;user&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;octocat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--admin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/drone/#linter:-untrusted-repositories-cannot-mount-host-volumes&#34;&gt;Linter: untrusted repositories cannot mount host volumes.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Thats because the &lt;a href=&#34;https://docs.drone.io/pipeline/docker/syntax/volumes/host/&#34;&gt;repository is not trusted&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;You have to set the trust as an admin of drone through the GUI or through the CLI with&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;drone&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;repo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--trusted&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;your/repo&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you&#39;re not an admin the above command returns a success but you&#39;ll see that the trust has not changed if you run&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;drone&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;repo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;info&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;your/repo&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;argocd&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/argocd/&#34;&gt;ArgoCD&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce ArgoCD.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://argo-cd.readthedocs.io/en/stable/&#34;&gt;Argo CD&lt;/a&gt; is a declarative, GitOps continuous delivery tool for Kubernetes.&lt;/p&gt; &lt;p&gt;Argo CD follows the GitOps pattern of using Git repositories as the source of truth for defining the desired application state. Kubernetes manifests can be specified in several ways:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;kustomize applications&lt;/li&gt; &lt;li&gt;helm charts&lt;/li&gt; &lt;li&gt;jsonnet files&lt;/li&gt; &lt;li&gt;Plain directory of YAML/json manifests&lt;/li&gt; &lt;li&gt;Any custom config management tool configured as a config management plugin, for example with &lt;a href=&#34;#using-helmfile&#34;&gt;helmfile&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Argo CD automates the deployment of the desired application states in the specified target environments. Application deployments can track updates to branches, tags, or pinned to a specific version of manifests at a Git commit. See tracking strategies for additional details about the different &lt;a href=&#34;https://argo-cd.readthedocs.io/en/stable/user-guide/tracking_strategies/&#34;&gt;tracking strategies available&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;shellcheck&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/shellcheck/&#34;&gt;Shellcheck&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce shellcheck.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.shellcheck.net/&#34;&gt;Shellcheck&lt;/a&gt; is a linting tool to finds bugs in your shell scripts.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/koalaman/shellcheck#installing&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;shellcheck
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Errors&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.shellcheck.net/wiki/SC2143&#34;&gt;SC2143: Use &lt;code&gt;grep -q&lt;/code&gt; instead of comparing output with &lt;code&gt;[ -n .. ]&lt;/code&gt;.&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Problematic code:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;find&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;IMG[0-9]&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Images found&#34;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Correct code:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;find&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-q&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;IMG[0-9]&#39;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Images found&#34;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Rationale:&lt;/p&gt; &lt;p&gt;The problematic code has to iterate the entire directory and read all matching lines into memory before making a decision.&lt;/p&gt; &lt;p&gt;The correct code is cleaner and stops at the first matching line, avoiding both iterating the rest of the directory and reading data into memory.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;automating-processes&#34;&gt;Automating Processes&lt;/h3&gt; &lt;h4 id=&#34;copier&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/copier/&#34;&gt;copier&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce copier.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/copier-org/copier&#34;&gt;Copier&lt;/a&gt; is a library and CLI app for rendering project templates.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Works with local paths and Git URLs.&lt;/li&gt; &lt;li&gt;Your project can include any file and Copier can dynamically replace values in any kind of text file.&lt;/li&gt; &lt;li&gt;It generates a beautiful output and takes care of not overwriting existing files unless instructed to do so.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;This long article covers:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/copier/#installation&#34;&gt;Installation&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/copier/#basic-concepts&#34;&gt;Basic concepts&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/copier/#usage&#34;&gt;Usage&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;cruft&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/cruft/&#34;&gt;cruft&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Suggest to use copier instead.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/copier-org/copier&#34;&gt;copier&lt;/a&gt; looks a more maintained solution nowadays.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;letsencrypt&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/letsencrypt/&#34;&gt;letsencrypt&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce letsencrypt.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://letsencrypt.org/&#34;&gt;Letsencrypt&lt;/a&gt; is a free, automated, and open certificate authority brought to you by the nonprofit Internet Security Research Group (ISRG). Basically it gives away SSL certificates, which are required to configure webservers to use HTTPS instead of HTTP for example.&lt;/p&gt; &lt;p&gt;In the article you can also find:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/letsencrypt/#configure-a-wildcard-dns-when-the-provider-is-not-supported&#34;&gt;How to configure a wildcard dns when the provider is not supported&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;storage&#34;&gt;Storage&lt;/h3&gt; &lt;h4 id=&#34;openzfs-storage-planning&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/zfs_storage_planning/&#34;&gt;OpenZFS storage planning&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Introduce ZFS storage planning.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Analyze the Exos X18 of 16TB disk.&lt;/p&gt; &lt;table&gt; &lt;thead&gt; &lt;tr&gt; &lt;th&gt;Specs&lt;/th&gt; &lt;th&gt;IronWolf&lt;/th&gt; &lt;th&gt;IronWolf Pro&lt;/th&gt; &lt;th&gt;Exos 7E8 8TB&lt;/th&gt; &lt;th&gt;Exos 7E10 8TB&lt;/th&gt; &lt;th&gt;Exos X18 16TB&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Technology&lt;/td&gt; &lt;td&gt;CMR&lt;/td&gt; &lt;td&gt;CMR&lt;/td&gt; &lt;td&gt;CMR&lt;/td&gt; &lt;td&gt;SMR&lt;/td&gt; &lt;td&gt;CMR&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Bays&lt;/td&gt; &lt;td&gt;1-8&lt;/td&gt; &lt;td&gt;1-24&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Capacity&lt;/td&gt; &lt;td&gt;1-12TB&lt;/td&gt; &lt;td&gt;2-20TB&lt;/td&gt; &lt;td&gt;8TB&lt;/td&gt; &lt;td&gt;8TB&lt;/td&gt; &lt;td&gt;16 TB&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;RPM&lt;/td&gt; &lt;td&gt;5,400 RPM (3-6TB)&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;RPM&lt;/td&gt; &lt;td&gt;5,900 RPM (1-3TB)&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;RPM&lt;/td&gt; &lt;td&gt;7,200 RPM (8-12TB)&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Speed&lt;/td&gt; &lt;td&gt;180MB/s (1-12TB)&lt;/td&gt; &lt;td&gt;214-260MB/s (4-18TB)&lt;/td&gt; &lt;td&gt;249 MB/s&lt;/td&gt; &lt;td&gt;255 MB/s&lt;/td&gt; &lt;td&gt;258 MB/s&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Cache&lt;/td&gt; &lt;td&gt;64MB (1-4TB)&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Cache&lt;/td&gt; &lt;td&gt;256MB (3-12TB)&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Power Consumption&lt;/td&gt; &lt;td&gt;10.1 W&lt;/td&gt; &lt;td&gt;10.1 W&lt;/td&gt; &lt;td&gt;12.81 W&lt;/td&gt; &lt;td&gt;11.03 W&lt;/td&gt; &lt;td&gt;9.31 W&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Power Consumption Rest&lt;/td&gt; &lt;td&gt;7.8 W&lt;/td&gt; &lt;td&gt;7.8 W&lt;/td&gt; &lt;td&gt;7.64 W&lt;/td&gt; &lt;td&gt;7.06 W&lt;/td&gt; &lt;td&gt;5.08 W&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Workload&lt;/td&gt; &lt;td&gt;180TB/yr&lt;/td&gt; &lt;td&gt;300TB/yr&lt;/td&gt; &lt;td&gt;550TB/yr&lt;/td&gt; &lt;td&gt;550TB/yr&lt;/td&gt; &lt;td&gt;550TB/yr&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;MTBF&lt;/td&gt; &lt;td&gt;1 million&lt;/td&gt; &lt;td&gt;1 million&lt;/td&gt; &lt;td&gt;2 millions&lt;/td&gt; &lt;td&gt;2 millions&lt;/td&gt; &lt;td&gt;2.5 millions&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Warranty&lt;/td&gt; &lt;td&gt;3 years&lt;/td&gt; &lt;td&gt;5 years&lt;/td&gt; &lt;td&gt;5 years&lt;/td&gt; &lt;td&gt;5 years&lt;/td&gt; &lt;td&gt;5 years&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Price&lt;/td&gt; &lt;td&gt;From $60 (2022)&lt;/td&gt; &lt;td&gt;From $83 (2022)&lt;/td&gt; &lt;td&gt;249$ (2022)&lt;/td&gt; &lt;td&gt;249$ (2022)&lt;/td&gt; &lt;td&gt;249$ (2023)&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;openzfs&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/sanoid/&#34;&gt;OpenZFS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#usage&#34;&gt;How to create a pool and datasets.&lt;/a&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#configure-nfs&#34;&gt;Configure NFS.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;With ZFS you can share a specific dataset via NFS. If for whatever reason the dataset does not mount, then the export will not be available to the application, and the NFS client will be blocked.&lt;/p&gt; &lt;p&gt;You still must install the necessary daemon software to make the share available. For example, if you wish to share a dataset via NFS, then you need to install the NFS server software, and it must be running. Then, all you need to do is flip the sharing NFS switch on the dataset, and it will be immediately available.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#backup&#34;&gt;Backup.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Please remember that &lt;a href=&#34;https://serverfault.com/questions/2888/why-is-raid-not-a-backup&#34;&gt;RAID is not a backup&lt;/a&gt;, it guards against one kind of hardware failure. There&#39;s lots of failure modes that it doesn&#39;t guard against though:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;File corruption&lt;/li&gt; &lt;li&gt;Human error (deleting files by mistake)&lt;/li&gt; &lt;li&gt;Catastrophic damage (someone dumps water onto the server)&lt;/li&gt; &lt;li&gt;Viruses and other malware&lt;/li&gt; &lt;li&gt;Software bugs that wipe out data&lt;/li&gt; &lt;li&gt;Hardware problems that wipe out data or cause hardware damage (controller malfunctions, firmware bugs, voltage spikes, ...)&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;That&#39;s why you still need to make backups.&lt;/p&gt; &lt;p&gt;ZFS has the builtin feature to make snapshots of the pool. A snapshot is a first class read-only filesystem. It is a mirrored copy of the state of the filesystem at the time you took the snapshot. They are persistent across reboots, and they don&#39;t require any additional backing store; they use the same storage pool as the rest of your data.&lt;/p&gt; &lt;p&gt;If you remember &lt;a href=&#34;https://pthree.org/2012/12/14/zfs-administration-part-ix-copy-on-write/&#34;&gt;ZFS&#39;s awesome nature of copy-on-write&lt;/a&gt; filesystems, you will remember the discussion about Merkle trees. A ZFS snapshot is a copy of the Merkle tree in that state, except we make sure that the snapshot of that Merkle tree is never modified.&lt;/p&gt; &lt;p&gt;Creating snapshots is near instantaneous, and they are cheap. However, once the data begins to change, the snapshot will begin storing data. If you have multiple snapshots, then multiple deltas will be tracked across all the snapshots. However, depending on your needs, snapshots can still be exceptionally cheap.&lt;/p&gt; &lt;p&gt;The article also includes:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#zfs-snapshot-lifecycle-management&#34;&gt;ZFS snapshot lifecycle management&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#restore-a-backup&#34;&gt;Restore a backup&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce Sanoid.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/jimsalterjrs/sanoid/&#34;&gt;Sanoid&lt;/a&gt; is the most popular tool right now, with it you can create, automatically thin, and monitor snapshots and pool health from a single eminently human-readable TOML config file.&lt;/p&gt; &lt;p&gt;The article includes:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/sanoid/#installation&#34;&gt;Installation&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/sanoid/#configuration&#34;&gt;Configuration&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Pros and cons&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/sanoid/#usage&#34;&gt;Usage&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/sanoid/#troubleshooting&#34;&gt;Troubleshooting&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#get-compress-ratio-of-a-filesystem&#34;&gt;Get compress ratio of a filesystem.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;compressratio&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;filesystem&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Use the recursive flag.&lt;/p&gt; &lt;p&gt;&lt;code&gt;recursive&lt;/code&gt; is not set by default, so the dataset&#39;s children won&#39;t be backed up unless you set this option.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt; [main/backup]
   use_template = daily
   recursive = yes
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#see-how-much-space-do-your-snapshots-consume&#34;&gt;See how much space do your snapshots consume.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;When a snapshot is created, its space is initially shared between the snapshot and the file system, and possibly with previous snapshots. As the file system changes, space that was previously shared becomes unique to the snapshot, and thus is counted in the snapshot’s &lt;code&gt;used&lt;/code&gt; property.&lt;/p&gt; &lt;p&gt;Additionally, deleting snapshots can increase the amount of space that is unique for use by other snapshots.&lt;/p&gt; &lt;p&gt;Note: The value for a snapshot’s space referenced property is the same as that for the file system when the snapshot was created.&lt;/p&gt; &lt;p&gt;You can display the amount of space that is consumed by snapshots and descendant file systems by using the &lt;code&gt;zfs list -o space&lt;/code&gt; command.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;NAME&lt;span class=&#34;w&#34;&gt;                             &lt;/span&gt;AVAIL&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;USED&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;USEDSNAP&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;USEDDS&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;USEDREFRESERV&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;USEDCHILD
rpool&lt;span class=&#34;w&#34;&gt;                            &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;.2G&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;5&lt;/span&gt;.16G&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4&lt;/span&gt;.52M&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;5&lt;/span&gt;.15G
rpool/ROOT&lt;span class=&#34;w&#34;&gt;                       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;.2G&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3&lt;/span&gt;.06G&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;31K&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3&lt;/span&gt;.06G
rpool/ROOT/solaris&lt;span class=&#34;w&#34;&gt;               &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;.2G&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3&lt;/span&gt;.06G&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;55&lt;/span&gt;.0M&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;.78G&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;224M
rpool/ROOT/solaris@install&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;55&lt;/span&gt;.0M&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;-
rpool/ROOT/solaris/var&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;.2G&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;224M&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;.51M&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;221M&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
rpool/ROOT/solaris/var@install&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;.51M&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;-
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;From this output, you can see the amount of space that is:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;AVAIL: The amount of space available to the dataset and all its children, assuming that there is no other activity in the pool.&lt;/li&gt; &lt;li&gt; &lt;p&gt;USED: The amount of space consumed by this dataset and all its descendants. This is the value that is checked against this dataset&#39;s quota and reservation. The space used does not include this dataset&#39;s reservation, but does take into account the reservations of any descendants datasets.&lt;/p&gt; &lt;p&gt;The used space of a snapshot is the space referenced exclusively by this snapshot. If this snapshot is destroyed, the amount of &lt;code&gt;used&lt;/code&gt; space will be freed. Space that is shared by multiple snapshots isn&#39;t accounted for in this metric. * USEDSNAP: Space being consumed by snapshots of each data set * USEDDS: Space being used by the dataset itself * USEDREFRESERV: Space being used by a refreservation set on the dataset that would be freed if it was removed. * USEDCHILD: Space being used by the children of this dataset.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Other space properties are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;LUSED: The amount of space that is &#34;logically&#34; consumed by this dataset and all its descendents. It ignores the effect of &lt;code&gt;compression&lt;/code&gt; and &lt;code&gt;copies&lt;/code&gt; properties, giving a quantity closer to the amount of data that aplication ssee. However it does include space consumed by metadata.&lt;/li&gt; &lt;li&gt;REFER: The amount of data that is accessible by this dataset, which may or may not be shared with other dataserts in the pool. When a snapshot or clone is created, it initially references the same amount of space as the filesystem or snapshot it was created from, since its contents are identical.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#rename-or-move-a-dataset&#34;&gt;Rename or move a dataset.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;NOTE: if you want to rename the topmost dataset look at &lt;a href=&#34;#rename-the-topmost-dataset&#34;&gt;rename the topmost dataset&lt;/a&gt; instead. File systems can be renamed by using the &lt;code&gt;zfs rename&lt;/code&gt; command. You can perform the following operations:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Change the name of a file system.&lt;/li&gt; &lt;li&gt;Relocate the file system within the ZFS hierarchy.&lt;/li&gt; &lt;li&gt;Change the name of a file system and relocate it within the ZFS hierarchy.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The following example uses the &lt;code&gt;rename&lt;/code&gt; subcommand to rename of a file system from &lt;code&gt;kustarz&lt;/code&gt; to &lt;code&gt;kustarz_old&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rename&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank/home/kustarz&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank/home/kustarz_old
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The following example shows how to use zfs &lt;code&gt;rename&lt;/code&gt; to relocate a file system:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rename&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank/home/maybee&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank/ws/maybee
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;In this example, the &lt;code&gt;maybee&lt;/code&gt; file system is relocated from &lt;code&gt;tank/home&lt;/code&gt; to &lt;code&gt;tank/ws&lt;/code&gt;. When you relocate a file system through rename, the new location must be within the same pool and it must have enough disk space to hold this new file system. If the new location does not have enough disk space, possibly because it has reached its quota, rename operation fails.&lt;/p&gt; &lt;p&gt;The rename operation attempts an unmount/remount sequence for the file system and any descendent file systems. The rename command fails if the operation is unable to unmount an active file system. If this problem occurs, you must forcibly unmount the file system.&lt;/p&gt; &lt;p&gt;You&#39;ll loose the snapshots though, as explained below.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#rename-the-topmost-dataset&#34;&gt;Rename the topmost dataset.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you want to rename the topmost dataset you &lt;a href=&#34;https://github.com/openzfs/zfs/issues/4681&#34;&gt;need to rename the pool too&lt;/a&gt; as these two are tied.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;status&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;pool:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tets
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;state:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ONLINE
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;scrub:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;none&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;requested
config:

&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;NAME&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;STATE&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;READ&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;WRITE&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;CKSUM
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;tets&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;c0d1&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;c1d0&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;c1d1&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;

errors:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;No&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;known&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;data&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;errors
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To fix this, first export the pool:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tets
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;And then imported it with the correct name:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;import&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tets&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;After the import completed, the pool contains the correct name:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;status&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;pool:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;test&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;state:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ONLINE
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;scrub:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;none&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;requested
config:

&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;NAME&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;STATE&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;READ&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;WRITE&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;CKSUM
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;test&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;c0d1&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;c1d0&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;c1d1&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;

errors:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;No&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;known&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;data&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;errors
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Now you may need to fix the ZFS mountpoints for each dataset&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;mountpoint&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;/opt/zones/[Newmountpoint]&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;ZFSPOOL/&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;ROOTor&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;other&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;filesystem&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#rename-or-move-snapshots&#34;&gt;Rename or move snapshots.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If the dataset has snapshots you need to rename them too. They must be renamed within the same pool and dataset from which they were created though. For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rename&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank/home/cindys@083006&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank/home/cindys@today
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;In addition, the following shortcut syntax is equivalent to the preceding syntax:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rename&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank/home/cindys@083006&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;today
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The following snapshot rename operation is not supported because the target pool and file system name are different from the pool and file system where the snapshot was created:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rename&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank/home/cindys@today&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pool/home/cindys@saturday
cannot&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rename&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;to&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;pool/home/cindys@today&#39;&lt;/span&gt;:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;snapshots&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;must&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;be&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;part&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;of&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;same
dataset
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can recursively rename snapshots by using the &lt;code&gt;zfs rename -r&lt;/code&gt; command. For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list
NAME&lt;span class=&#34;w&#34;&gt;                         &lt;/span&gt;USED&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;AVAIL&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;REFER&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;MOUNTPOINT
users&lt;span class=&#34;w&#34;&gt;                        &lt;/span&gt;270K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;16&lt;/span&gt;.5G&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;22K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;/users
users/home&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;76K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;16&lt;/span&gt;.5G&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;22K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;/users/home
users/home@yesterday&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;22K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-
users/home/markm&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;18K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;16&lt;/span&gt;.5G&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;18K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;/users/home/markm
users/home/markm@yesterday&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;18K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-
users/home/marks&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;18K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;16&lt;/span&gt;.5G&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;18K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;/users/home/marks
users/home/marks@yesterday&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;18K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-
users/home/neil&lt;span class=&#34;w&#34;&gt;               &lt;/span&gt;18K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;16&lt;/span&gt;.5G&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;18K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;/users/home/neil
users/home/neil@yesterday&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;18K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-
$:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rename&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;users/home@yesterday&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;@2daysago
$:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;users/home
NAME&lt;span class=&#34;w&#34;&gt;                        &lt;/span&gt;USED&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;AVAIL&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;REFER&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;MOUNTPOINT
users/home&lt;span class=&#34;w&#34;&gt;                   &lt;/span&gt;76K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;16&lt;/span&gt;.5G&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;22K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;/users/home
users/home@2daysago&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;22K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-
users/home/markm&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;18K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;16&lt;/span&gt;.5G&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;18K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;/users/home/markm
users/home/markm@2daysago&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;18K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-
users/home/marks&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;18K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;16&lt;/span&gt;.5G&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;18K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;/users/home/marks
users/home/marks@2daysago&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;18K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-
users/home/neil&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;18K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;16&lt;/span&gt;.5G&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;18K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;/users/home/neil
users/home/neil@2daysago&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;18K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#see-the-differences-between-two-backups&#34;&gt;See the differences between two backups.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To identify the differences between two snapshots, use syntax similar to the following:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;diff&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank/home/tim@snap1&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank/home/tim@snap2
M&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;/tank/home/tim/
+&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;/tank/home/tim/fileB
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The following table summarizes the file or directory changes that are identified by the &lt;code&gt;zfs diff&lt;/code&gt; command.&lt;/p&gt; &lt;table&gt; &lt;thead&gt; &lt;tr&gt; &lt;th&gt;File or Directory Change&lt;/th&gt; &lt;th&gt;Identifier&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;File or directory has been modified or file or directory link has changed&lt;/td&gt; &lt;td&gt;M&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;File or directory is present in the older snapshot but not in the more recent snapshot&lt;/td&gt; &lt;td&gt;—&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;File or directory is present in the more recent snapshot but not in the older snapshot&lt;/td&gt; &lt;td&gt;+&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;File or directory has been renamed&lt;/td&gt; &lt;td&gt;R&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#create-a-cold-backup-of-a-series-of-datasets&#34;&gt;Create a cold backup of a series of datasets.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you&#39;ve used the &lt;code&gt;-o keyformat=raw -o keylocation=file:///etc/zfs/keys/home.key&lt;/code&gt; arguments to encrypt your datasets you can&#39;t use a &lt;code&gt;keyformat=passphase&lt;/code&gt; encryption on the cold storage device. You need to copy those keys on the disk. One way of doing it is to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Create a 100M LUKS partition protected with a passphrase where you store the keys.&lt;/li&gt; &lt;li&gt;The rest of the space is left for a partition for the zpool.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#clear-a-permanent-zfs-error-in-a-healthy-pool&#34;&gt;Clear a permanent ZFS error in a healthy pool.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Sometimes when you do a &lt;code&gt;zpool status&lt;/code&gt; you may see that the pool is healthy but that there are &#34;Permanent errors&#34; that may point to files themselves or directly to memory locations.&lt;/p&gt; &lt;p&gt;You can read &lt;a href=&#34;https://github.com/openzfs/zfs/discussions/9705&#34;&gt;this long discussion&lt;/a&gt; on what does these permanent errors mean, but what solved the issue for me was to run a new scrub&lt;/p&gt; &lt;p&gt;&lt;code&gt;zpool scrub my_pool&lt;/code&gt;&lt;/p&gt; &lt;p&gt;It takes a long time to run, so be patient.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#zfs-pool-is-in-suspended-mode&#34;&gt;ZFS pool is in suspended mode.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Probably because you&#39;ve unplugged a device without unmounting it.&lt;/p&gt; &lt;p&gt;If you want to remount the device &lt;a href=&#34;https://github.com/openzfsonosx/zfs/issues/104#issuecomment-30344347&#34;&gt;you can follow these steps&lt;/a&gt; to symlink the new devfs entries to where zfs thinks the vdev is. That way you can regain access to the pool without a reboot.&lt;/p&gt; &lt;p&gt;So if zpool status says the vdev is /dev/disk2s1, but the reattached drive is at disk4, then do the following:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;disk2s1
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ln&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;disk4s1&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;disk2s1
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;clear&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-F&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;WD_1TB
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;WD_1TB
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;disk2s1
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;import&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;WD_1TB
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you don&#39;t care about the zpool anymore, sadly your only solution is to &lt;a href=&#34;https://github.com/openzfs/zfs/issues/5242&#34;&gt;reboot the server&lt;/a&gt;. Real ugly, so be careful when you umount zpools.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/sanoid/#prune-snapshots&#34;&gt;Prune snapshots.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you want to manually prune the snapshots after you tweaked &lt;code&gt;sanoid.conf&lt;/code&gt; you can run:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sanoid&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--prune-snapshots
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/sanoid/#send-encrypted-backups-to-a-encrypted-dataset&#34;&gt;Send encrypted backups to a encrypted dataset.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;syncoid&lt;/code&gt;&#39;s default behaviour is to create the destination dataset without encryption so the snapshots are transferred and can be read without encryption. You can check this with the &lt;code&gt;zfs get encryption,keylocation,keyformat&lt;/code&gt; command both on source and destination.&lt;/p&gt; &lt;p&gt;To prevent this from happening you have to [pass the &lt;code&gt;--sendoptions=&#39;w&#39;](https://github.com/jimsalterjrs/sanoid/issues/548) to&lt;/code&gt;syncoid&lt;code&gt;so that it tells zfs to send a raw stream. If you do so, you also need to [transfer the key file](https://github.com/jimsalterjrs/sanoid/issues/648) to the destination server so that it can do a&lt;/code&gt;zfs loadkey` and then mount the dataset. For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;server-host:$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;filesystem
NAME&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;USED&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;AVAIL&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;REFER&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;MOUNTPOINT
server_data&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;232M&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;38&lt;/span&gt;.1G&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;230M&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;/var/server_data
server_data/log&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;111K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;38&lt;/span&gt;.1G&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;111K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;/var/server_data/log
server_data/mail&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;111K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;38&lt;/span&gt;.1G&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;111K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;/var/server_data/mail
server_data/nextcloud&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;111K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;38&lt;/span&gt;.1G&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;111K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;/var/server_data/nextcloud
server_data/postgres&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;111K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;38&lt;/span&gt;.1G&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;111K&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;/var/server_data/postgres

server-host:$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;keylocation&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;server_data/nextcloud
NAME&lt;span class=&#34;w&#34;&gt;                   &lt;/span&gt;PROPERTY&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;VALUE&lt;span class=&#34;w&#34;&gt;                                    &lt;/span&gt;SOURCE
server_data/nextcloud&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;keylocation&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;file:///root/zfs_dataset_nextcloud_pass&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;

server-host:$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;syncoid&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--recursive&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--skip-parent&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--sendoptions&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;w&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;server_data&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;root@192.168.122.94:backup_pool
INFO:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Sending&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;oldest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;full&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;snapshot&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;server_data/log@autosnap_2021-06-18_18:33:42_yearly&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;~&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;49&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;KB&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;to&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;new&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;target&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;filesystem:
&lt;span class=&#34;m&#34;&gt;17&lt;/span&gt;.0KiB&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;:00:00&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;.79MiB/s&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[=================================================&lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt;                                                                                                  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;34&lt;/span&gt;%
INFO:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Updating&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;new&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;target&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;filesystem&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;with&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;incremental&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;server_data/log@autosnap_2021-06-18_18:33:42_yearly&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;...&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;syncoid_caedrium.com_2021-06-22:10:12:55&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;~&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;KB&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;:
&lt;span class=&#34;m&#34;&gt;41&lt;/span&gt;.2KiB&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;:00:00&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;78&lt;/span&gt;.4KiB/s&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[===================================================================================================================================================]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;270&lt;/span&gt;%
INFO:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Sending&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;oldest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;full&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;snapshot&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;server_data/mail@autosnap_2021-06-18_18:33:42_yearly&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;~&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;49&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;KB&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;to&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;new&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;target&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;filesystem:
&lt;span class=&#34;m&#34;&gt;17&lt;/span&gt;.0KiB&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;:00:00&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;921KiB/s&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[=================================================&lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt;                                                                                                  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;34&lt;/span&gt;%
INFO:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Updating&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;new&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;target&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;filesystem&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;with&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;incremental&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;server_data/mail@autosnap_2021-06-18_18:33:42_yearly&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;...&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;syncoid_caedrium.com_2021-06-22:10:13:14&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;~&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;KB&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;:
&lt;span class=&#34;m&#34;&gt;41&lt;/span&gt;.2KiB&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;:00:00&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;49&lt;/span&gt;.4KiB/s&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[===================================================================================================================================================]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;270&lt;/span&gt;%
INFO:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Sending&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;oldest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;full&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;snapshot&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;server_data/nextcloud@autosnap_2021-06-18_18:33:42_yearly&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;~&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;49&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;KB&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;to&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;new&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;target&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;filesystem:
&lt;span class=&#34;m&#34;&gt;17&lt;/span&gt;.0KiB&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;:00:00&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;870KiB/s&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[=================================================&lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt;                                                                                                  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;34&lt;/span&gt;%
INFO:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Updating&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;new&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;target&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;filesystem&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;with&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;incremental&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;server_data/nextcloud@autosnap_2021-06-18_18:33:42_yearly&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;...&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;syncoid_caedrium.com_2021-06-22:10:13:42&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;~&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;KB&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;:
&lt;span class=&#34;m&#34;&gt;41&lt;/span&gt;.2KiB&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;:00:00&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;50&lt;/span&gt;.4KiB/s&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[===================================================================================================================================================]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;270&lt;/span&gt;%
INFO:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Sending&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;oldest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;full&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;snapshot&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;server_data/postgres@autosnap_2021-06-18_18:33:42_yearly&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;~&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;50&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;KB&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;to&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;new&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;target&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;filesystem:
&lt;span class=&#34;m&#34;&gt;17&lt;/span&gt;.0KiB&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;:00:00&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;.36MiB/s&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[===============================================&lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt;                                                                                                    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;33&lt;/span&gt;%
INFO:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Updating&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;new&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;target&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;filesystem&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;with&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;incremental&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;server_data/postgres@autosnap_2021-06-18_18:33:42_yearly&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;...&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;syncoid_caedrium.com_2021-06-22:10:14:11&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;~&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;KB&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;:
&lt;span class=&#34;m&#34;&gt;41&lt;/span&gt;.2KiB&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;:00:00&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;48&lt;/span&gt;.9KiB/s&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[===================================================================================================================================================]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;270&lt;/span&gt;%

server-host:$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;scp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/root/zfs_dataset_nextcloud_pass&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;192&lt;/span&gt;.168.122.94:
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;backup-host:$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;keylocation&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;file:///root/zfs_dataset_nextcloud_pass&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;backup_pool/nextcloud
backup-host:$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;load-key&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;backup_pool/nextcloud
backup-host:$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mount&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;backup_pool/nextcloud
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you also want to keep the &lt;code&gt;encryptionroot&lt;/code&gt; you need to &lt;a href=&#34;https://github.com/jimsalterjrs/sanoid/issues/614&#34;&gt;let zfs take care of the recursion instead of syncoid&lt;/a&gt;. In this case you can&#39;t use syncoid&#39;s stuff like &lt;code&gt;--exclude&lt;/code&gt; from the manpage of zfs:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;-R, --replicate
   Generate a replication stream package, which will replicate the specified file system, and all descendent file systems, up to the named snapshot.  When received, all properties, snap‐
   shots, descendent file systems, and clones are preserved.

   If the -i or -I flags are used in conjunction with the -R flag, an incremental replication stream is generated.  The current values of properties, and current snapshot and file system
   names are set when the stream is received.  If the -F flag is specified when this stream is received, snapshots and file systems that do not exist on the sending side are destroyed.
   If the -R flag is used to send encrypted datasets, then -w must also be specified.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;In this case this should work:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;/sbin/syncoid&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--recursive&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--force-delete&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--sendoptions&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Rw&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zpool/backups&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zfs-recv@10.29.3.27:zpool/backups
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#repair-a-degraded-pool&#34;&gt;Repair a DEGRADED pool.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;First let’s offline the device we are going to replace:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;offline&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank0&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ata-WDC_WD2003FZEX-00SRLA0_WD-xxxxxxxxxxxx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Now let us have a look at the pool status.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;status

NAME&lt;span class=&#34;w&#34;&gt;                                            &lt;/span&gt;STATE&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;READ&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;WRITE&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;CKSUM
tank0&lt;span class=&#34;w&#34;&gt;                                           &lt;/span&gt;DEGRADED&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;raidz2-1&lt;span class=&#34;w&#34;&gt;                                      &lt;/span&gt;DEGRADED&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;ata-TOSHIBA_HDWN180_xxxxxxxxxxxx&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;ata-TOSHIBA_HDWN180_xxxxxxxxxxxx&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;ata-TOSHIBA_HDWN180_xxxxxxxxxxxx&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;ata-WDC_WD80EFZX-68UW8N0_xxxxxxxx&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;ata-TOSHIBA_HDWG180_xxxxxxxxxxxx&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;ata-TOSHIBA_HDWG180_xxxxxxxxxxxx&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;ata-WDC_WD2003FZEX-00SRLA0_WD-xxxxxxxxxxxx&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;OFFLINE&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;ata-ST4000VX007-2DT166_xxxxxxxx&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Sweet, the device is offline (last time it didn&#39;t show as offline for me, but the offline command returned a status code of 0).&lt;/p&gt; &lt;p&gt;Time to shut the server down and physically replace the disk.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;shutdown&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-h&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;now
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;When you start again the server, it’s time to instruct ZFS to replace the removed device with the disk we just installed.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;replace&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank0&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;ata-WDC_WD2003FZEX-00SRLA0_WD-xxxxxxxxxxxx&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;/dev/disk/by-id/ata-TOSHIBA_HDWG180_xxxxxxxxxxxx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;status&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank0

pool:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;main
state:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;DEGRADED
status:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;One&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;or&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;more&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;devices&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;is&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;currently&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;being&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;resilvered.&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;The&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;will
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;to&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt;,&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;possibly&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;degraded&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;state.
action:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Wait&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;the&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;resilver&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;to&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;complete.
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;scan:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;resilver&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;progress&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;since&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Fri&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Sep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;22&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;12&lt;/span&gt;:40:28&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2023&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4&lt;/span&gt;.00T&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;scanned&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;at&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;6&lt;/span&gt;.85G/s,&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;222G&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;issued&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;at&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;380M/s,&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;24&lt;/span&gt;.3T&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;total
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;54&lt;/span&gt;.7G&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;resilvered,&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.89%&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;,&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;18&lt;/span&gt;:28:03&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;to&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;go
NAME&lt;span class=&#34;w&#34;&gt;                                              &lt;/span&gt;STATE&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;READ&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;WRITE&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;CKSUM
tank0&lt;span class=&#34;w&#34;&gt;                                             &lt;/span&gt;DEGRADED&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;raidz2-1&lt;span class=&#34;w&#34;&gt;                                        &lt;/span&gt;DEGRADED&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;ata-TOSHIBA_HDWN180_xxxxxxxxxxxx&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;ata-TOSHIBA_HDWN180_xxxxxxxxxxxx&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;ata-TOSHIBA_HDWN180_xxxxxxxxxxxx&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;ata-WDC_WD80EFZX-68UW8N0_xxxxxxxx&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;ata-TOSHIBA_HDWG180_xxxxxxxxxxxx&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;ata-TOSHIBA_HDWG180_xxxxxxxxxxxx&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;replacing-6&lt;span class=&#34;w&#34;&gt;                                   &lt;/span&gt;DEGRADED&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;ata-WDC_WD2003FZEX-00SRLA0_WD-xxxxxxxxxxxx&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;OFFLINE&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;ata-TOSHIBA_HDWG180_xxxxxxxxxxxx&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;resilvering&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;ata-ST4000VX007-2DT166_xxxxxxxx&lt;span class=&#34;w&#34;&gt;               &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The disk is replaced and getting resilvered (which may take a long time to run (18 hours in a 8TB disk in my case).&lt;/p&gt; &lt;p&gt;Once the resilvering is done; this is what the pool looks like.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list

NAME&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;SIZE&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;ALLOC&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;FREE&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;EXPANDSZ&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;FRAG&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;CAP&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;DEDUP&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;HEALTH&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;ALTROOT
tank0&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;43&lt;/span&gt;.5T&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;33&lt;/span&gt;.0T&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;.5T&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;14&lt;/span&gt;.5T&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;7&lt;/span&gt;%&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;75&lt;/span&gt;%&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;.00x&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you want to read other blogs that have covered the same topic check out &lt;a href=&#34;https://madaboutbrighton.net/articles/replace-disk-in-zfs-pool&#34;&gt;1&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Stop a ZFS scrub.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;scrub&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;my_pool
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#mount-a-dataset-that-is-encrypted&#34;&gt;Mount a dataset that is encrypted.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If your dataset is encrypted using a key file you need to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Mount the device that has your keys&lt;/li&gt; &lt;li&gt;Import the pool without loading the key because you want to override the keylocation attribute with zfs load-key. Without the -l option, any encrypted datasets won&#39;t be mounted, which is what you want.&lt;/li&gt; &lt;li&gt;Load the key(s) for the dataset(s)&lt;/li&gt; &lt;li&gt;Mount the dataset(s).&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;import&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rpool&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# without the `-l` option!&lt;/span&gt;
zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;load-key&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-L&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;file:///path/to/keyfile&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rpool
zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mount&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rpool
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#umount-a-pool&#34;&gt;Umount a pool.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pool-name
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#repair-a-degraded-pool&#34;&gt;Improve the Repair a DEGRADED pool instructions.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;First you need to make sure that it is in fact a problem of the disk. Check the &lt;code&gt;dmesg&lt;/code&gt; to see if there are any traces of reading errors, or SATA cable errors.&lt;/p&gt; &lt;p&gt;A friend suggested to mark the disk as healthy and do a resilver on the same disk. If the error is reproduced in the next days, then replace the disk. A safer approach is to resilver on a new disk, analyze the disk when it&#39;s not connected to the pool, and if you feel it&#39;s safe then save it as a cold spare.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#remove-all-snapshots-of-a-dataset&#34;&gt;Remove all snapshots of a dataset.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;snapshot&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;path/to/dataset&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tail&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n+2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tac&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;xargs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;destroy&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;zfs-prometheus-exporter&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/zfs_exporter/&#34;&gt;ZFS Prometheus exporter&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the ZFS exporter.&lt;/p&gt; &lt;p&gt;You can use a &lt;a href=&#34;https://github.com/pdf/zfs_exporter&#34;&gt;zfs exporter&lt;/a&gt; to create alerts on your ZFS pools, filesystems, snapshots and volumes.&lt;/p&gt; &lt;p&gt;It&#39;s not easy to match the exporter metrics with the output of &lt;code&gt;zfs list -o space&lt;/code&gt;. Here is a correlation table:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;USED: &lt;code&gt;zfs_dataset_used_bytes{type=&#34;filesystem&#34;}&lt;/code&gt;&lt;/li&gt; &lt;li&gt;AVAIL: &lt;code&gt;zfs_dataset_available_bytes{type=&#34;filesystem&#34;}&lt;/code&gt;&lt;/li&gt; &lt;li&gt;LUSED: &lt;code&gt;zfs_dataset_logical_used_bytes{type=&#34;filesystem&#34;}&lt;/code&gt;&lt;/li&gt; &lt;li&gt;USEDDS: &lt;code&gt;zfs_dataset_used_by_dataset_bytes=&#34;filesystem&#34;}&lt;/code&gt;&lt;/li&gt; &lt;li&gt;USEDSNAP: Currently there &lt;a href=&#34;https://github.com/pdf/zfs_exporter/issues/32&#34;&gt;is no published metric&lt;/a&gt; to get this data. You can either use &lt;code&gt;zfs_dataset_used_bytes - zfs_dataset_used_by_dataset_bytes&lt;/code&gt; which will show wrong data if the dataset has children or try to do &lt;code&gt;sum by (hostname,filesystem) (zfs_dataset_used_bytes{type=&#39;snapshot&#39;})&lt;/code&gt; which returns smaller sizes than expected.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;It also covers the &lt;a href=&#34;https://lyz-code.github.io/blue-book/zfs_exporter/#installation&#34;&gt;installation&lt;/a&gt; as well as some nice &lt;a href=&#34;https://lyz-code.github.io/blue-book/zfs_exporter/#configure-the-alerts&#34;&gt;alerts&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Improve alerts.&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Correction: Update the alerts to the more curated version.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/zfs_exporter/#useful-inhibits&#34;&gt;Useful inhibits.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Some you may want to inhibit some of these rules for some of your datasets. These subsections should be added to the &lt;code&gt;alertmanager.yml&lt;/code&gt; file under the &lt;code&gt;inhibit_rules&lt;/code&gt; field.&lt;/p&gt; &lt;p&gt;Ignore snapshots on some datasets: Sometimes you don&#39;t want to do snapshots on a dataset&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;target_matchers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;alertname = ZfsDatasetWithNoSnapshotsError&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;hostname = my_server_1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;filesystem = tmp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Ignore snapshots growth: Sometimes you don&#39;t mind if the size of the data saved in the filesystems doesn&#39;t change too much between snapshots doesn&#39;t change much specially in the most frequent backups because you prefer to keep the backup cadence. It&#39;s interesting to have the alert though so that you can get notified of the datasets that don&#39;t change that much so you can tweak your backup policy (even if zfs snapshots are almost free).&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;target_matchers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;alertname =~ &#34;ZfsSnapshotType(Frequently|Hourly)SizeError&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;filesystem =~ &#34;(media/(docs|music))&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;monitoring&#34;&gt;Monitoring&lt;/h3&gt; &lt;h4 id=&#34;loki&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/loki/&#34;&gt;Loki&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce loki.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://grafana.com/docs/loki/latest/&#34;&gt;Loki&lt;/a&gt; is a set of components that can be composed into a fully featured logging stack.&lt;/p&gt; &lt;p&gt;Unlike other logging systems, Loki is built around the idea of only indexing metadata about your logs: labels (just like Prometheus labels). Log data itself is then compressed and stored in chunks in object stores such as Amazon Simple Storage Service (S3) or Google Cloud Storage (GCS), or even locally on the filesystem.&lt;/p&gt; &lt;p&gt;A small index and highly compressed chunks simplifies the operation and significantly lowers the cost of Loki.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/loki/#installation&#34;&gt;How to install loki.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;There are &lt;a href=&#34;https://grafana.com/docs/loki/latest/setup/install/&#34;&gt;many ways to install Loki&lt;/a&gt;, we&#39;re going to do it using &lt;code&gt;docker-compose&lt;/code&gt; taking &lt;a href=&#34;https://raw.githubusercontent.com/grafana/loki/v2.9.1/production/docker-compose.yaml&#34;&gt;their example as a starting point&lt;/a&gt; and complementing our already existent &lt;a href=&#34;https://lyz-code.github.io/blue-book/grafana/#installation&#34;&gt;grafana docker-compose&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;It makes use of the &lt;a href=&#34;https://grafana.com/docs/loki/latest/configure/#configuration-file-reference&#34;&gt;environment variables to configure Loki&lt;/a&gt;, that&#39;s why we have the &lt;code&gt;-config.expand-env=true&lt;/code&gt; flag in the command line launch.&lt;/p&gt; &lt;p&gt;In the grafana datasources directory add &lt;code&gt;loki.yaml&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;1&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;datasources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Loki&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;loki&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;access&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;proxy&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;orgId&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;http://loki:3100&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;basicAuth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;false&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;isDefault&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;editable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;a href=&#34;https://grafana.com/docs/loki/latest/storage/&#34;&gt;Storage configuration&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;Unlike other logging systems, Grafana Loki is built around the idea of only indexing metadata about your logs: labels (just like Prometheus labels). Log data itself is then compressed and stored in chunks in object stores such as S3 or GCS, or even locally on the filesystem. A small index and highly compressed chunks simplifies the operation and significantly lowers the cost of Loki.&lt;/p&gt; &lt;p&gt;Loki 2.0 brings an index mechanism named ‘boltdb-shipper’ and is what we now call Single Store. This type only requires one store, the object store, for both the index and chunks.&lt;/p&gt; &lt;p&gt;Loki 2.8 adds TSDB as a new mode for the Single Store and is now the recommended way to persist data in Loki as it improves query performance, reduces TCO and has the same feature parity as “boltdb-shipper”.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;grafana&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/grafana/&#34;&gt;Grafana&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce grafana.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://grafana.com/grafana&#34;&gt;Grafana&lt;/a&gt; is a web application to create dashboards.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://grafana.com/docs/grafana/latest/setup-grafana/installation/docker/#run-grafana-via-docker-compose&#34;&gt;Installation&lt;/a&gt;: We&#39;re going to install it with docker-compose and connect it to &lt;a href=&#34;https://lyz-code.github.io/blue-book/authentik/&#34;&gt;Authentik&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://goauthentik.io/integrations/services/grafana/&#34;&gt;Create the Authentik connection&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;Assuming that you have &lt;a href=&#34;https://lyz-code.github.io/blue-book/authentik/&#34;&gt;the terraform authentik provider configured&lt;/a&gt;, use the next terraform code:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;variable&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&#34;grafana_name&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;The name shown in the Grafana application.&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Grafana&#34;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;kr&#34;&gt;variable&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&#34;grafana_redirect_uri&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;The redirect url configured on Grafana.&#34;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;kr&#34;&gt;variable&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&#34;grafana_icon&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;The icon shown in the Grafana application&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;/application-icons/grafana.svg&#34;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;kr&#34;&gt;resource&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;&#34;authentik_application&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&#34;grafana&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;var.grafana_name&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;slug&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;grafana&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;protocol_provider&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;authentik_provider_oauth2.grafana.id&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;meta_icon&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;var.grafana_icon&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;lifecycle&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;ignore_changes&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;      # The terraform provider is continuously changing the attribute even though it&#39;s set&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;meta_icon&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;kr&#34;&gt;resource&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;&#34;authentik_provider_oauth2&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&#34;grafana&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;               &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;var.grafana_name&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;client_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;grafana&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;authorization_flow&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;data.authentik_flow.default-authorization-flow.id&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;property_mappings&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;data.authentik_scope_mapping.email.id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;data.authentik_scope_mapping.openid.id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;data.authentik_scope_mapping.profile.id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;redirect_uris&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;var.grafana_redirect_uri&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;signing_key&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;data.authentik_certificate_key_pair.default.id&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;access_token_validity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;minutes=120&#34;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;kr&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;&#34;authentik_certificate_key_pair&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&#34;default&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;authentik Self-signed Certificate&#34;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;kr&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;&#34;authentik_flow&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&#34;default-authorization-flow&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;slug&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;default-provider-authorization-implicit-consent&#34;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;kr&#34;&gt;output&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&#34;grafana_oauth_id&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;authentik_provider_oauth2.grafana.client_id&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;kr&#34;&gt;output&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&#34;grafana_oauth_secret&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;authentik_provider_oauth2.grafana.client_secret&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Install grafana.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;3.8&#34;&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;grafana&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;grafana/grafana-oss:${GRAFANA_VERSION:-latest}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;container_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;grafana&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;restart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;unless-stopped&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;data:/var/lib/grafana&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;networks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;grafana&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;monitorization&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;swag&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;env_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;.env&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;depends_on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;db&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;postgres:${DATABASE_VERSION:-15}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;restart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;unless-stopped&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;container_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;grafana-db&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;environment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;POSTGRES_DB=${GF_DATABASE_NAME:-grafana}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;POSTGRES_USER=${GF_DATABASE_USER:-grafana}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;POSTGRES_PASSWORD=${GF_DATABASE_PASSWORD:?database password required}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;networks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;grafana&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;db-data:/var/lib/postgresql/data&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;env_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;.env&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;networks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;grafana&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;external&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;grafana&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;monitorization&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;external&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;monitorization&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;swag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;external&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;swag&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;driver&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;local&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;driver_opts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;none&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;bind&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;device&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/data/grafana/app&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;db-data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;driver&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;local&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;driver_opts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;none&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;bind&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;device&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/data/grafana/database&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where the &lt;code&gt;monitorization&lt;/code&gt; network is where prometheus and the rest of the stack listens, and &lt;code&gt;swag&lt;/code&gt; the network to the gateway proxy.&lt;/p&gt; &lt;p&gt;It uses the &lt;code&gt;.env&lt;/code&gt; file to store the required &lt;a href=&#34;#configure-grafana&#34;&gt;configuration&lt;/a&gt;, to connect grafana with authentik you need to add the next variables:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;GF_AUTH_GENERIC_OAUTH_ENABLED&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;true&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;GF_AUTH_GENERIC_OAUTH_NAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;authentik&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;GF_AUTH_GENERIC_OAUTH_CLIENT_ID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;Client ID from above&amp;gt;&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;Client Secret from above&amp;gt;&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;GF_AUTH_GENERIC_OAUTH_SCOPES&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;openid profile email&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;GF_AUTH_GENERIC_OAUTH_AUTH_URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;https://authentik.company/application/o/authorize/&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;GF_AUTH_GENERIC_OAUTH_TOKEN_URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;https://authentik.company/application/o/token/&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;GF_AUTH_GENERIC_OAUTH_API_URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;https://authentik.company/application/o/userinfo/&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;GF_AUTH_SIGNOUT_REDIRECT_URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;https://authentik.company/application/o/&amp;lt;Slug of the application from above&amp;gt;/end-session/&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;GF_AUTH_OAUTH_AUTO_LOGIN&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;true&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;GF_AUTH_GENERIC_OAUTH_ROLE_ATTRIBUTE_PATH&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;contains(groups[*], &#39;Grafana Admins&#39;) &amp;amp;&amp;amp; &#39;Admin&#39; || contains(groups[*], &#39;Grafana Editors&#39;) &amp;amp;&amp;amp; &#39;Editor&#39; || &#39;Viewer&#39;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;In the configuration above you can see an example of a role mapping. Upon login, this configuration looks at the groups of which the current user is a member. If any of the specified group names are found, the user will be granted the resulting role in Grafana.&lt;/p&gt; &lt;p&gt;In the example shown above, one of the specified group names is &#34;Grafana Admins&#34;. If the user is a member of this group, they will be granted the &#34;Admin&#34; role in Grafana. If the user is not a member of the &#34;Grafana Admins&#34; group, it moves on to see if the user is a member of the &#34;Grafana Editors&#34; group. If they are, they are granted the &#34;Editor&#34; role. Finally, if the user is not found to be a member of either of these groups, it fails back to granting the &#34;Viewer&#34; role.&lt;/p&gt; &lt;p&gt;Also make sure in your configuration that &lt;code&gt;root_url&lt;/code&gt; is set correctly, otherwise your redirect url might get processed incorrectly. For example, if your grafana instance is running on the default configuration and is accessible behind a reverse proxy at &lt;a href=&#34;https://grafana.company&#34;&gt;https://grafana.company&lt;/a&gt;, your redirect url will end up looking like this, &lt;a href=&#34;https://grafana.company/&#34;&gt;https://grafana.company/&lt;/a&gt;. If you get &lt;code&gt;user does not belong to org&lt;/code&gt; error when trying to log into grafana for the first time via OAuth, check if you have an organization with the ID of 1, if not, then you have to add the following to your grafana config:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[users]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;auto_assign_org&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;auto_assign_org_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;lt;id-of-your-default-organization&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Once you&#39;ve made sure that the oauth works, go to &lt;code&gt;/admin/users&lt;/code&gt; and remove the &lt;code&gt;admin&lt;/code&gt; user.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/grafana/#configure-grafana&#34;&gt;Configure grafana.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Grafana has default and custom configuration files. You can customize your Grafana instance by modifying the custom configuration file or by using environment variables. To see the list of settings for a Grafana instance, refer to &lt;a href=&#34;https://grafana.com/docs/grafana/latest/administration/stats-and-license/#view-server-settings&#34;&gt;View server settings&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;To override an option use &lt;code&gt;GF_&amp;lt;SectionName&amp;gt;_&amp;lt;KeyName&amp;gt;&lt;/code&gt;. Where the &lt;code&gt;section name&lt;/code&gt; is the text within the brackets. Everything should be uppercase, &lt;code&gt;.&lt;/code&gt; and &lt;code&gt;-&lt;/code&gt; should be replaced by &lt;code&gt;_&lt;/code&gt;. For example, if you have these configuration settings:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;na&#34;&gt;instance_name&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;${HOSTNAME}&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[security]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;admin_user&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;admin&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[auth.google]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;client_secret&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;0ldS3cretKey&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[plugin.grafana-image-renderer]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;rendering_ignore_https_errors&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;true&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[feature_toggles]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;enable&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;newNavigation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can override variables on Linux machines with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;GF_DEFAULT_INSTANCE_NAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;my-instance
&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;GF_SECURITY_ADMIN_USER&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;owner
&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;GF_AUTH_GOOGLE_CLIENT_SECRET&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;newS3cretKey
&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;GF_PLUGIN_GRAFANA_IMAGE_RENDERER_RENDERING_IGNORE_HTTPS_ERRORS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;GF_FEATURE_TOGGLES_ENABLE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;newNavigation
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;And in the docker compose you can edit the &lt;code&gt;.env&lt;/code&gt; file. Mine looks similar to:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;GRAFANA_VERSION&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;latest
&lt;span class=&#34;nv&#34;&gt;GF_DEFAULT_INSTANCE_NAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;production&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;GF_SERVER_ROOT_URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;https://your.domain.org&#34;&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;GF_DATABASE_TYPE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;postgres
&lt;span class=&#34;nv&#34;&gt;DATABASE_VERSION&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;15&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;GF_DATABASE_HOST&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;grafana-db:5432
&lt;span class=&#34;nv&#34;&gt;GF_DATABASE_NAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;grafana
&lt;span class=&#34;nv&#34;&gt;GF_DATABASE_USER&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;grafana
&lt;span class=&#34;nv&#34;&gt;GF_DATABASE_PASSWORD&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;change-for-a-long-password&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;GF_DATABASE_SSL_MODE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;disable

&lt;span class=&#34;nv&#34;&gt;GF_AUTH_GENERIC_OAUTH_ENABLED&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;true&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;GF_AUTH_GENERIC_OAUTH_NAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;authentik&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;GF_AUTH_GENERIC_OAUTH_CLIENT_ID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;Client ID from above&amp;gt;&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;Client Secret from above&amp;gt;&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;GF_AUTH_GENERIC_OAUTH_SCOPES&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;openid profile email&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;GF_AUTH_GENERIC_OAUTH_AUTH_URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;https://authentik.company/application/o/authorize/&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;GF_AUTH_GENERIC_OAUTH_TOKEN_URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;https://authentik.company/application/o/token/&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;GF_AUTH_GENERIC_OAUTH_API_URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;https://authentik.company/application/o/userinfo/&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;GF_AUTH_SIGNOUT_REDIRECT_URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;https://authentik.company/application/o/&amp;lt;Slug of the application from above&amp;gt;/end-session/&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;GF_AUTH_OAUTH_AUTO_LOGIN&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;true&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;GF_AUTH_GENERIC_OAUTH_ROLE_ATTRIBUTE_PATH&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;contains(groups[*], &#39;Grafana Admins&#39;) &amp;amp;&amp;amp; &#39;Admin&#39; || contains(groups[*], &#39;Grafana Editors&#39;) &amp;amp;&amp;amp; &#39;Editor&#39; || &#39;Viewer&#39;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/grafana/#configure-datasources&#34;&gt;Configure datasources.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can manage data sources in Grafana by adding YAML configuration files in the &lt;code&gt;provisioning/datasources&lt;/code&gt; directory. Each config file can contain a list of datasources to add or update during startup. If the data source already exists, Grafana reconfigures it to match the provisioned configuration file.&lt;/p&gt; &lt;p&gt;The configuration file can also list data sources to automatically delete, called &lt;code&gt;deleteDatasources&lt;/code&gt;. Grafana deletes the data sources listed in &lt;code&gt;deleteDatasources&lt;/code&gt; before adding or updating those in the datasources list.&lt;/p&gt; &lt;p&gt;For example to &lt;a href=&#34;https://grafana.com/docs/grafana/latest/datasources/prometheus/&#34;&gt;configure a Prometheus datasource&lt;/a&gt; use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;1&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;datasources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Prometheus&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;prometheus&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;access&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;proxy&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Access mode - proxy (server in the UI) or direct (browser in the UI).&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;http://prometheus:9090&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;jsonData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;httpMethod&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;POST&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;manageAlerts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;prometheusType&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Prometheus&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;prometheusVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;2.44.0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cacheLevel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;High&#39;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;disableRecordingRules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;false&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;incrementalQueryOverlapWindow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;10m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;exemplarTraceIdDestinations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/grafana/#configure-dashboards&#34;&gt;Configure dashboards.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can manage dashboards in Grafana by adding one or more YAML config files in the &lt;code&gt;provisioning/dashboards&lt;/code&gt; directory. Each config file can contain a list of dashboards providers that load dashboards into Grafana from the local filesystem.&lt;/p&gt; &lt;p&gt;Create one file called &lt;code&gt;dashboards.yaml&lt;/code&gt; with the next contents:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;providers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# A uniquely identifiable name for the provider&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;file&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/etc/grafana/provisioning/dashboards/definitions&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then inside the config directory of your docker compose create the directory &lt;code&gt;provisioning/dashboards/definitions&lt;/code&gt; and add the json of the dashboards themselves. You can download them from the dashboard pages. For example:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://grafana.com/grafana/dashboards/1860-node-exporter-full/&#34;&gt;Node Exporter&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://grafana.com/grafana/dashboards/13659-blackbox-exporter-http-prober/&#34;&gt;Blackbox Exporter&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://grafana.com/grafana/dashboards/9578-alertmanager/&#34;&gt;Alertmanager&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/grafana/#configure-the-plugins&#34;&gt;Configure the plugins.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To install plugins in the Docker container, complete the following steps:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Pass the plugins you want to be installed to Docker with the &lt;code&gt;GF_INSTALL_PLUGINS&lt;/code&gt; environment variable as a comma-separated list.&lt;/li&gt; &lt;li&gt;This sends each plugin name to &lt;code&gt;grafana-cli plugins install ${plugin}&lt;/code&gt; and installs them when Grafana starts.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;run&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3000&lt;/span&gt;:3000&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--name&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;grafana&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-e&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;GF_INSTALL_PLUGINS=grafana-clock-panel, grafana-simple-json-datasource&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;grafana/grafana-oss
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To specify the version of a plugin, add the version number to the &lt;code&gt;GF_INSTALL_PLUGINS&lt;/code&gt; environment variable. For example: &lt;code&gt;GF_INSTALL_PLUGINS=grafana-clock-panel 1.0.1&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;To install a plugin from a custom URL, use the following convention to specify the URL: &lt;code&gt;&amp;lt;url to plugin zip&amp;gt;;&amp;lt;plugin install folder name&amp;gt;&lt;/code&gt;. For example: &lt;code&gt;GF_INSTALL_PLUGINS=https://github.com/VolkovLabs/custom-plugin.zip;custom-plugin&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Improve installation method.&lt;/p&gt; &lt;p&gt;Add more configuration values such as:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;GF_SERVER_ENABLE_GZIP=&#34;true&#34;

GF_AUTH_GENERIC_OAUTH_ALLOW_ASSIGN_GRAFANA_ADMIN=&#34;true&#34;

GF_LOG_MODE=&#34;console file&#34;
GF_LOG_LEVEL=&#34;info&#34;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/grafana/#configure-datasources&#34;&gt;Warning when configuring datasources.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Be careful to set the &lt;code&gt;timeInterval&lt;/code&gt; variable to the value of how often you scrape the data from the node exporter to avoid &lt;a href=&#34;https://github.com/rfmoz/grafana-dashboards/issues/137&#34;&gt;this issue&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;siem&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/alertmanager/&#34;&gt;SIEM&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/alertmanager/#route&#34;&gt;Alertmanager routes.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;A route block defines a node in a routing tree and its children. Its optional configuration parameters are inherited from its parent node if not set.&lt;/p&gt; &lt;p&gt;Every alert enters the routing tree at the configured top-level route, which must match all alerts (i.e. not have any configured matchers). It then traverses the child nodes. If continue is set to false, it stops after the first matching child. If continue is true on a matching node, the alert will continue matching against subsequent siblings. If an alert does not match any children of a node (no matching child nodes, or none exist), the alert is handled based on the configuration parameters of the current node.&lt;/p&gt; &lt;p&gt;A basic configuration would be:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;route&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;group_by&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;job&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;alertname&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;group_wait&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;30s&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;group_interval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;5m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;repeat_interval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;12h&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;receiver&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;email&#39;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;routes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;match&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alertname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Watchdog&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;receiver&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;null&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add Wazuh SIEM.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://wazuh.com/&#34;&gt;Wazuh&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;blackbox-exporter&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/blackbox_exporter/&#34;&gt;Blackbox Exporter&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/blackbox_exporter/#check-tcp-with-tls&#34;&gt;Check TCP with TLS.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you want to test for example if an LDAP is serving the correct certificate on the port 636 you can use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;tcp_ssl_connect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;prober&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;tcp&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;10s&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Ldap&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;my-ldap-server:636&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;tcp_ssl_connect&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;node-exporter&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/node_exporter/&#34;&gt;Node Exporter&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;Correction: Improve how to install it.&lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;authentication&#34;&gt;Authentication&lt;/h3&gt; &lt;h4 id=&#34;authentik&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/authentik/&#34;&gt;Authentik&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Authentik.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://goauthentik.io/&#34;&gt;Authentik&lt;/a&gt; is an open-source Identity Provider focused on flexibility and versatility.&lt;/p&gt; &lt;p&gt;What I like:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Is maintained and popular&lt;/li&gt; &lt;li&gt;It has a clean interface&lt;/li&gt; &lt;li&gt;They have their own &lt;a href=&#34;https://registry.terraform.io/providers/goauthentik/authentik/latest/docs/resources/application&#34;&gt;terraform provider&lt;/a&gt; Oo!&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;What I don&#39;t like:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;It&#39;s heavy focused on GUI interaction, but you can export the configuration to YAML files to be applied without the GUI interaction.&lt;/li&gt; &lt;li&gt;The documentation is oriented to developers and not users. It&#39;s a little difficult to get a grasp on how to do things in the platform without following blog posts.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;In the article you can also find:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/authentik/#installation&#34;&gt;How to install it&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/authentik/#terraform&#34;&gt;How to configure and use the terraform provider&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/authentik/#gitea&#34;&gt;How to configure some applications, such as gitea&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/authentik/#configure-the-invitation-flow&#34;&gt;How to configure the user registration by invitation link&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/authentik/#use-blueprints&#34;&gt;How to use blueprints&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/authentik/#configure-the-invitation-flow&#34;&gt;Configure the invitation flow with terraform.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/authentik/#hide-and-application-from-a-user&#34;&gt;Hide and application from a user.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Application access can be configured using (Policy) Bindings. Click on an application in the applications list, and select the Policy / Group / User Bindings tab. There you can bind users/groups/policies to grant them access. When nothing is bound, everyone has access. You can use this to grant access to one or multiple users/groups, or dynamically give access using policies.&lt;/p&gt; &lt;p&gt;With terraform you can use &lt;code&gt;authentik_policy_binding&lt;/code&gt;, for example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;resource&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;&#34;authentik_policy_binding&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&#34;admin&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;target&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;authentik_application.gitea.uuid&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;authentik_group.admins.id&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;order&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/authentik/#configure-password-recovery&#34;&gt;Configure password recovery.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Password recovery is not set by default, in the article you can find the terraform resources needed for it to work.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/authentik/#protect-applications-that-don&#39;t-have-authentication&#34;&gt;Protect applications that don&#39;t have authentication.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Some applications don&#39;t have authentication, for example &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/prometheus/&#34;&gt;prometheus&lt;/a&gt;. You can use Authentik in front of such applications to add the authentication and authorization layer.&lt;/p&gt; &lt;p&gt;Authentik can be used as a (very) simple reverse proxy by using its Provider feature with the regular &#34;Proxy&#34; setting. This let&#39;s you wrap authentication around a sub-domain / app where it normally wouldn&#39;t have authentication (or not the type of auth that you would specifically want) and then have Authentik handle the proxy forwarding and Auth.&lt;/p&gt; &lt;p&gt;In this mode, there is no domain level nor &#39;integrated&#39; authentication into your desired app; Authentik becomes both your reverse proxy and auth for this one particular app or (sub) domain. This mode does not forward authentication nor let you log in into any app. It&#39;s just acts like an authentication wrapper.&lt;/p&gt; &lt;p&gt;It&#39;s best to use a normal reverse proxy out front of Authentik. This adds a second layer of routing to deal with but Authentik is not NGINX or a reverse proxy system, so it does not have that many configuration options.&lt;/p&gt; &lt;p&gt;We&#39;ll use the following fake domains in this example:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Authentik domain: auth.yourdomain.com&lt;/li&gt; &lt;li&gt;App domain: app.yourdomain.com&lt;/li&gt; &lt;li&gt;Nginx: nginx.yourdomain.com&lt;/li&gt; &lt;li&gt;Authentik&#39;s docker conter name: auth_server&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The steps are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Configure the proxy provider:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;c1&#34;&gt;# ---------------&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;# -- Variables --&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;# ---------------&lt;/span&gt;

&lt;span class=&#34;kr&#34;&gt;variable&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&#34;prometheus_url&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;The url to access the service.&#34;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;# ----------&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;# -- Data --&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;# ----------&lt;/span&gt;

&lt;span class=&#34;kr&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;&#34;authentik_flow&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&#34;default-authorization-flow&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;slug&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;default-provider-authorization-implicit-consent&#34;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;# --------------------&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;# --    Provider    --&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;# --------------------&lt;/span&gt;

&lt;span class=&#34;kr&#34;&gt;resource&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;&#34;authentik_provider_proxy&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&#34;prometheus&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;               &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Prometheus&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;internal_host&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;http://prometheus:9090&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;external_host&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;var.prometheus_url&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;authorization_flow&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;data.authentik_flow.default-authorization-flow.id&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;internal_host_ssl_validation&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;false&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Finish the installation of prometheus.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/authentik/#monitorization&#34;&gt;Disregard monitorization.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I&#39;ve skimmed through the prometheus metrics exposed at &lt;code&gt;:9300/metrics&lt;/code&gt; in the core and they aren&#39;t that useful :(&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/authentik/#i-can&#39;t-log-in-to-authentik&#34;&gt;Troubleshoot I can&#39;t log in to authentik.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;In case you can&#39;t login anymore, perhaps due to an incorrectly configured stage or a failed flow import, you can create a recovery key.&lt;/p&gt; &lt;p&gt;To create the key, run the following command:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;run&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--it&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;authentik&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;bash
ak&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;create_recovery_key&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;akadmin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This will output a link, that can be used to instantly gain access to authentik as the user specified above. The link is valid for amount of years specified above, in this case, 1 year.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;operating-systems&#34;&gt;Operating Systems&lt;/h2&gt; &lt;h3 id=&#34;linux&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/&#34;&gt;Linux&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Interesting learning pages.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://explainshell.com/&#34;&gt;https://explainshell.com/&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://linuxcommandlibrary.com/&#34;&gt;https://linuxcommandlibrary.com/&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;linux-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/&#34;&gt;Linux Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#use-a-pass-password-in-a-makefile&#34;&gt;Use a &lt;code&gt;pass&lt;/code&gt; password in a Makefile.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;TOKEN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;?=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;shell&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;bash&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;/usr/bin/pass show path/to/token&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;nf&#34;&gt;diff&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;@AUTHENTIK_TOKEN&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;TOKEN&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;terraform&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;plan
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#install-a-new-font&#34;&gt;Install a new font.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Install a font manually by downloading the appropriate &lt;code&gt;.ttf&lt;/code&gt; or &lt;code&gt;otf&lt;/code&gt; files and placing them into &lt;code&gt;/usr/local/share/fonts&lt;/code&gt; (system-wide), &lt;code&gt;~/.local/share/fonts&lt;/code&gt; (user-specific) or &lt;code&gt;~/.fonts&lt;/code&gt; (user-specific). These files should have the permission 644 (&lt;code&gt;-rw-r--r--&lt;/code&gt;), otherwise they may not be usable.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#get-vpn-password-from-pass&#34;&gt;Get VPN password from &lt;code&gt;pass&lt;/code&gt;.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To be able to retrieve the user and password from pass you need to run the openvpn command with the next flags:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;bash&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;openvpn --config config.ovpn  --auth-user-pass &amp;lt;(echo -e &#39;user_name\n&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;pass&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;show&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;vpn&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#39;)&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Assuming that &lt;code&gt;vpn&lt;/code&gt; is an entry of your &lt;code&gt;pass&lt;/code&gt; password store.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#measure-the-performance-iops-of-a-disk&#34;&gt;Measure the performance, IOPS of a disk.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To measure disk IOPS performance in Linux, you can use the &lt;code&gt;fio&lt;/code&gt; tool. Install it with&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;fio
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then you need to go to the directory where your disk is mounted. The test is done by performing read/write operations in this directory.&lt;/p&gt; &lt;p&gt;To do a random read/write operation test an 8 GB file will be created. Then &lt;code&gt;fio&lt;/code&gt; will read/write a 4KB block (a standard block size) with the 75/25% by the number of reads and writes operations and measure the performance.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;fio&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--randrepeat&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--ioengine&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;libaio&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--direct&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--gtod_reduce&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--name&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;fiotest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--filename&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;testfio&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--bs&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;4k&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--iodepth&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;64&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--size&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;8G&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--readwrite&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;randrw&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--rwmixread&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;75&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#what-is-/var/log/tallylog&#34;&gt;What is &lt;code&gt;/var/log/tallylog&lt;/code&gt;.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;/var/log/tallylog&lt;/code&gt; is the file where the &lt;code&gt;PAM&lt;/code&gt; linux module (used for authentication of the machine) keeps track of the failed ssh logins in order to temporarily block users.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#manage-users&#34;&gt;Manage users.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Change main group of user&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;usermod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-g&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;group_name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;user_name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Add user to group&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;usermod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-G&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;group_name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;user_name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Remove user from group.&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;usermod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-G&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;remaining_group_names&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;user_name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You have to execute &lt;code&gt;groups {{ user }}&lt;/code&gt; get the list and pass the remaining to the above command&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Change uid and gid of the user&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;usermod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-u&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;newuid&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;login&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;
groupmod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-g&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;newgid&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;group&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;
find&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-user&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;olduid&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-exec&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;chown&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-h&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;newuid&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\;&lt;/span&gt;
find&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-group&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;oldgid&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-exec&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;chgrp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-h&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;newgid&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\;&lt;/span&gt;
usermod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-g&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;newgid&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;login&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#manage-ssh-keys&#34;&gt;Manage ssh keys.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Generate ed25519 key&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ssh-keygen&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ed25519&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;path_to_keyfile&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Generate RSA key&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ssh-keygen&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rsa&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-b&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4096&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;path_to_keyfile&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Generate different comment&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ssh-keygen&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ed25519&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;path_to_keyfile&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-C&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;email&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Generate key headless, batch&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ssh-keygen&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ed25519&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;path_to_keyfile&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-q&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-N&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Generate public key from private key&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ssh-keygen&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-y&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;path_to_keyfile&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;path_to_public_key_file&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Get fingerprint of key &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ssh-keygen&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-lf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;path_to_key&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#measure-the-network-performance-between-two-machines&#34;&gt;Measure the network performance between two machines.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Install &lt;code&gt;iperf3&lt;/code&gt; with &lt;code&gt;apt-get install iperf3&lt;/code&gt; on both server and client.&lt;/p&gt; &lt;p&gt;On the server system run:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;server#:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;iperf3&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;-i&lt;/code&gt;: the interval to provide periodic bandwidth updates&lt;/li&gt; &lt;li&gt;&lt;code&gt;-s&lt;/code&gt;: listen as a server&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;On the client system:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;client#:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;iperf3&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-w&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;1M&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;60&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;server&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;hostname&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;or&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;address&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;-i&lt;/code&gt;: the interval to provide periodic bandwidth updates&lt;/li&gt; &lt;li&gt;&lt;code&gt;-w&lt;/code&gt;: the socket buffer size (which affects the TCP Window). The buffer size is also set on the server by this client command.&lt;/li&gt; &lt;li&gt;&lt;code&gt;-t&lt;/code&gt;: the time to run the test in seconds&lt;/li&gt; &lt;li&gt;&lt;code&gt;-c&lt;/code&gt;: connect to a listening server at…&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Sometimes is interesting to test both ways as they may return different outcomes&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#force-umount-nfs-mounted-directory&#34;&gt;Force umount nfs mounted directory.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;umount&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;path/to/mounted/dir
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#configure-fstab-to-mount-nfs&#34;&gt;Configure fstab to mount nfs.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;NFS stands for ‘Network File System’. This mechanism allows Unix machines to share files and directories over the network. Using this feature, a Linux machine can mount a remote directory (residing in a NFS server machine) just like a local directory and can access files from it.&lt;/p&gt; &lt;p&gt;An NFS share can be mounted on a machine by adding a line to the &lt;code&gt;/etc/fstab&lt;/code&gt; file.&lt;/p&gt; &lt;p&gt;The default syntax for &lt;code&gt;fstab&lt;/code&gt; entry of NFS mounts is as follows.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Server:/path/to/export /local_mountpoint nfs &amp;lt;options&amp;gt; 0 0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;Server&lt;/code&gt;: The hostname or IP address of the NFS server where the exported directory resides.&lt;/li&gt; &lt;li&gt;&lt;code&gt;/path/to/export&lt;/code&gt;: The shared directory (exported folder) path.&lt;/li&gt; &lt;li&gt;&lt;code&gt;/local_mountpoint&lt;/code&gt;: Existing directory in the host where you want to mount the NFS share.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;You can specify a number of options that you want to set on the NFS mount:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;soft/hard&lt;/code&gt;: When the mount option &lt;code&gt;hard&lt;/code&gt; is set, if the NFS server crashes or becomes unresponsive, the NFS requests will be retried indefinitely. You can set the mount option &lt;code&gt;intr&lt;/code&gt;, so that the process can be interrupted. When the NFS server comes back online, the process can be continued from where it was while the server became unresponsive.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;When the option &lt;code&gt;soft&lt;/code&gt; is set, the process will be reported an error when the NFS server is unresponsive after waiting for a period of time (defined by the &lt;code&gt;timeo&lt;/code&gt; option). In certain cases &lt;code&gt;soft&lt;/code&gt; option can cause data corruption and loss of data. So, it is recommended to use &lt;code&gt;hard&lt;/code&gt; and &lt;code&gt;intr&lt;/code&gt; options.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;noexec&lt;/code&gt;: Prevents execution of binaries on mounted file systems. This is useful if the system is mounting a non-Linux file system via NFS containing incompatible binaries.&lt;/li&gt; &lt;li&gt;&lt;code&gt;nosuid&lt;/code&gt;: Disables set-user-identifier or set-group-identifier bits. This prevents remote users from gaining higher privileges by running a setuid program.&lt;/li&gt; &lt;li&gt;&lt;code&gt;tcp&lt;/code&gt;: Specifies the NFS mount to use the TCP protocol.&lt;/li&gt; &lt;li&gt;&lt;code&gt;udp&lt;/code&gt;: Specifies the NFS mount to use the UDP protocol.&lt;/li&gt; &lt;li&gt;&lt;code&gt;nofail&lt;/code&gt;: Prevent issues when rebooting the host. The downside is that if you have services that depend on the volume to be mounted they won&#39;t behave as expected.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#fix-limit-on-the-number-of-inotify-watches&#34;&gt;Fix limit on the number of inotify watches.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Programs that sync files such as dropbox, git etc use inotify to notice changes to the file system. The limit can be see by -&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/sys/fs/inotify/max_user_watches
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;For me, it shows &lt;code&gt;65536&lt;/code&gt;. When this limit is not enough to monitor all files inside a directory it throws this error.&lt;/p&gt; &lt;p&gt;If you want to increase the amount of inotify watchers, run the following in a terminal:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;fs.inotify.max_user_watches&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;100000&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tee&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/sysctl.conf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sysctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where &lt;code&gt;100000&lt;/code&gt; is the desired number of inotify watches.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#get-class-of-a-window&#34;&gt;Get class of a window.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use &lt;code&gt;xprop&lt;/code&gt; and click the window.&lt;/p&gt; &lt;p&gt;Get the current brightness level with &lt;code&gt;cat /sys/class/backlight/intel_backlight/brightness&lt;/code&gt;. Imagine it&#39;s &lt;code&gt;1550&lt;/code&gt;, then if you want to lower the brightness use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;500&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/sys/class/backlight/intel_backlight/brightness
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#ssh-tunnel&#34;&gt;SSH tunnel.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ssh&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-D&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;9090&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-N&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;user@host
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#fix-the-ssh-client-kex_exchange_identification:-read:-connection-reset-by-peer-error&#34;&gt;Fix the SSH client kex_exchange_identification: read: Connection reset by peer error.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Restart the &lt;code&gt;ssh&lt;/code&gt; service.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#automatic-reboot-after-power-failure&#34;&gt;Automatic reboot after power failure.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;That&#39;s not something you can control in your operating system. That&#39;s what the BIOS is for. In most BIOS setups there&#39;ll be an option like After power loss with possible values like Power off and Reboot.&lt;/p&gt; &lt;p&gt;You can also edit &lt;code&gt;/etc/default/grub&lt;/code&gt; and add:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;GRUB_RECORDFAIL_TIMEOUT=5
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then run:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update-grub
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This will make your machine display the boot options for 5 seconds before it boot the default option (instead of waiting forever for you to choose one).&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#ssh-tunnel&#34;&gt;Add sshuttle information link.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you need a more powerful ssh tunnel you can try &lt;a href=&#34;https://sshuttle.readthedocs.io/en/stable/overview.html&#34;&gt;sshuttle&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#reset-failed-systemd-services&#34;&gt;Reset failed systemd services.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use systemctl to remove the failed status. To reset all units with failed status:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reset-failed
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;or just your specific unit:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reset-failed&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;openvpn-server@intranert.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#get-the-current-git-branch&#34;&gt;Get the current git branch.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;branch&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--show-current
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#install-latest-version-of-package-from-backports&#34;&gt;Install latest version of package from backports.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Add the backports repository:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;vi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/apt/sources.list.d/bullseye-backports.list
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;deb http://deb.debian.org/debian bullseye-backports main contrib
deb-src http://deb.debian.org/debian bullseye-backports main contrib
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Configure the package to be pulled from backports&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;vi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/apt/preferences.d/90_zfs
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Package: src:zfs-linux
Pin: release n=bullseye-backports
Pin-Priority: 990
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#rename-multiple-files-matching-a-pattern&#34;&gt;Rename multiple files matching a pattern.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;There is &lt;code&gt;rename&lt;/code&gt; that looks nice, but you need to install it. Using only &lt;code&gt;find&lt;/code&gt; you can do:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;find&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;*yml&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-exec&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;bash&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;echo mv $0 ${0/yml/yaml}&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If it shows what you expect, remove the &lt;code&gt;echo&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#force-ssh-to-use-password-authentication&#34;&gt;Force ssh to use password authentication.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ssh&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;PreferredAuthentications&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;password&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;PubkeyAuthentication&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;no&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;exampleUser@example.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; feat(linux_snippets#Do a tail -f with grep): Do a tail -f with grep&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;tail&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;file&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--line-buffered&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;my_pattern
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#check-if-a-program-exists-in-the-user&#39;s-path&#34;&gt;Check if a program exists in the user&#39;s PATH.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;the_command&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Example use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;!&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;the_command&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/null
&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;the_command&amp;gt; could not be found&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/qbittorrent/#tools&#34;&gt;Add interesting tools to explore.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/buroa/qbittools&#34;&gt;qbittools&lt;/a&gt;: a feature rich CLI for the management of torrents in qBittorrent.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/StuffAnThings/qbit_manage&#34;&gt;qbit_manage&lt;/a&gt;: tool will help manage tedious tasks in qBittorrent and automate them.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#limit-the-resources-a-docker-is-using&#34;&gt;Limit the resources a docker is using.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can either use limits in the &lt;code&gt;docker&lt;/code&gt; service itself, see &lt;a href=&#34;https://unix.stackexchange.com/questions/537645/how-to-limit-docker-total-resources&#34;&gt;1&lt;/a&gt; and &lt;a href=&#34;https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html&#34;&gt;2&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Or/and you can limit it for each docker, see &lt;a href=&#34;https://www.baeldung.com/ops/docker-memory-limit&#34;&gt;1&lt;/a&gt; and &lt;a href=&#34;https://docs.docker.com/config/containers/resource_constraints/&#34;&gt;2&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#wipe-a-disk&#34;&gt;Wipe a disk.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Overwrite it many times &lt;a href=&#34;https://lyz-code.github.io/blue-book/hard_drive_health/#check-the-health-of-a-disk-with-badblocks&#34;&gt;with badblocks&lt;/a&gt;.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;badblocks&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-wsv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-b&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4096&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sde&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tee&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;disk_wipe_log.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#impose-load-on-a-system-to-stress-it&#34;&gt;Impose load on a system to stress it.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;stress

stress&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--cpu&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;That will fill up the usage of 2 cpus. To run 1 vm stressor using 1GB of virtual memory for 60s, enter:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;stress&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--vm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--vm-bytes&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;1G&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--vm-keep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;60s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can also stress io with &lt;code&gt;--io 4&lt;/code&gt;, for example to spawn 4 workers.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#get-the-latest-tag-of-a-git-repository&#34;&gt;Get the latest tag of a git repository.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;describe&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--tags&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--abbrev&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#configure-gpg-agent-cache-ttl&#34;&gt;Configure gpg-agent cache ttl.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The user configuration (in &lt;code&gt;~/.gnupg/gpg-agent.conf&lt;/code&gt;) can only define the default and maximum caching duration; it can&#39;t be disabled.&lt;/p&gt; &lt;p&gt;The &lt;code&gt;default-cache-ttl&lt;/code&gt; option sets the timeout (in seconds) after the last GnuPG activity (so it resets if you use it), the &lt;code&gt;max-cache-ttl&lt;/code&gt; option set the timespan (in seconds) it caches after entering your password. The default value is 600 seconds (10 minutes) for &lt;code&gt;default-cache-ttl&lt;/code&gt; and 7200 seconds (2 hours) for max-cache-ttl.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;default-cache-ttl 21600
max-cache-ttl 21600
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;For this change to take effect, you need to end the session by restarting &lt;code&gt;gpg-agent&lt;/code&gt;.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;gpgconf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--kill&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;gpg-agent
gpg-agent&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--daemon&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--use-standard-socket
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#get-return-code-of-failing-find-exec&#34;&gt;Get return code of failing find exec.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;When you run &lt;code&gt;find . -exec ls {} \;&lt;/code&gt; even if the command run in the &lt;code&gt;exec&lt;/code&gt; returns a status code different than 0 &lt;a href=&#34;https://serverfault.com/questions/905031/how-can-i-make-find-return-non-0-if-exec-command-fails&#34;&gt;you&#39;ll get an overall status code of 0&lt;/a&gt; which makes difficult to catch errors in bash scripts.&lt;/p&gt; &lt;p&gt;You can instead use &lt;code&gt;xargs&lt;/code&gt;, for example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;find&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/tmp/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-iname&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;*.sh&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-print0&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;xargs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-0&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;shellcheck
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This will run &lt;code&gt;shellcheck file_name&lt;/code&gt; for each of the files found by the &lt;code&gt;find&lt;/code&gt; command.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#accept-new-ssh-keys-by-default&#34;&gt;Accept new ssh keys by default.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;While common wisdom is not to disable host key checking, there is a built-in option in SSH itself to do this. It is relatively unknown, since it&#39;s new (added in Openssh 6.5).&lt;/p&gt; &lt;p&gt;This is done with &lt;code&gt;-o StrictHostKeyChecking=accept-new&lt;/code&gt;. Or if you want to use it for all hosts you can add the next lines to your &lt;code&gt;~/.ssh/config&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Host *
  StrictHostKeyChecking accept-new
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;WARNING: use this only if you absolutely trust the IP\hostname you are going to SSH to:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ssh&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;StrictHostKeyChecking&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;accept-new&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mynewserver.example.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Note, &lt;code&gt;StrictHostKeyChecking=no&lt;/code&gt; will add the public key to &lt;code&gt;~/.ssh/known_hosts&lt;/code&gt; even if the key was changed. &lt;code&gt;accept-new&lt;/code&gt; is only for new hosts. From the man page:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;If this flag is set to “accept-new” then ssh will automatically add new host keys to the user known hosts files, but will not permit connections to hosts with changed host keys. If this flag is set to “no” or “off”, ssh will automatically add new host keys to the user known hosts files and allow connections to hosts with changed hostkeys to proceed, subject to some restrictions. If this flag is set to ask (the default), new host keys will be added to the user known host files only after the user has confirmed that is what they really want to do, and ssh will refuse to connect to hosts whose host key has changed. The host keys of known hosts will be verified automatically in all cases.&lt;/p&gt; &lt;/blockquote&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#do-not-add-trailing-/-to-ls&#34;&gt;Do not add trailing / to ls.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Probably, your &lt;code&gt;ls&lt;/code&gt; is aliased or defined as a function in your config files.&lt;/p&gt; &lt;p&gt;Use the full path to &lt;code&gt;ls&lt;/code&gt; like:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;/bin/ls&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/mysql/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#convert-png-to-svg&#34;&gt;Convert png to svg.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Inkscape has got an awesome auto-tracing tool.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Install Inkscape using &lt;code&gt;sudo apt-get install inkscape&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Import your image&lt;/li&gt; &lt;li&gt;Select your image&lt;/li&gt; &lt;li&gt;From the menu bar, select Path &amp;gt; Trace Bitmap Item&lt;/li&gt; &lt;li&gt;Adjust the tracing parameters as needed&lt;/li&gt; &lt;li&gt;Save as svg&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Check their &lt;a href=&#34;https://inkscape.org/en/doc/tutorials/tracing/tutorial-tracing.html&#34;&gt;tracing tutorial&lt;/a&gt; for more information.&lt;/p&gt; &lt;p&gt;Once you are comfortable with the tracing options. You can automate it by using &lt;a href=&#34;https://inkscape.org/en/doc/inkscape-man.html&#34;&gt;CLI of Inkscape&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#redirect-stdout-and-stderr-of-a-cron-job-to-a-file&#34;&gt;Redirect stdout and stderr of a cron job to a file.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;*/1 * * * * /home/ranveer/vimbackup.sh &amp;gt;&amp;gt; /home/ranveer/vimbackup.log 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#error-when-unmounting-a-device-target-is-busy&#34;&gt;Error when unmounting a device Target is busy.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Check the processes that are using the mountpoint with &lt;code&gt;lsof /path/to/mountpoint&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Kill those processes&lt;/li&gt; &lt;li&gt;Try the umount again&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;If that fails, you can use &lt;code&gt;umount -l&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;rtorrent&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/afew/&#34;&gt;Rtorrent&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;Correction: Remove unneeded dependencies when installing.&lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Deprecate it in favour of qbittorrent.&lt;/p&gt; &lt;p&gt;Use &lt;a href=&#34;https://lyz-code.github.io/blue-book/qbittorrent/&#34;&gt;qbittorrent&lt;/a&gt; instead.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;aleph&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/&#34;&gt;aleph&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add application operations.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/#upgrade-aleph&#34;&gt;How to upgrade it&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/#create-aleph-admins&#34;&gt;Create Aleph admins&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/#remove-a-group&#34;&gt;Remove a group&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/#ingest-gets-stuck&#34;&gt;Ingest gets stuck.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It looks that Aleph doesn&#39;t yet give an easy way to debug it. It can be seen in the next webs:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/alephdata/aleph/issues/2124&#34;&gt;Improve the UX for bulk uploading and processing of large number of files&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/alephdata/aleph/issues/1839&#34;&gt;Document ingestion gets stuck effectively at 100%&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/alephdata/aleph/discussions/1525&#34;&gt;Display detailed ingestion status to see if everything is alright and when the collection is ready&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Some interesting ideas I&#39;ve extracted while diving into these issues is that:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;You can also upload files using the &lt;a href=&#34;https://github.com/alephdata/alephclient&#34;&gt;&lt;code&gt;alephclient&lt;/code&gt; python command line tool&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Some of the files might fail to be processed without leaving any hint to the uploader or the viewer.&lt;/li&gt; &lt;li&gt;This results in an incomplete dataset and the users don&#39;t get to know that the dataset is incomplete. This is problematic if the completeness of the dataset is crucial for an investigation.&lt;/li&gt; &lt;li&gt;There is no way to upload only the files that failed to be processed without re-uploading the entire set of documents or manually making a list of the failed documents and re-uploading them&lt;/li&gt; &lt;li&gt;There is no way for uploaders or Aleph admins to see an overview of processing errors to figure out why some files are failing to be processed without going through docker logs (which is not very user-friendly)&lt;/li&gt; &lt;li&gt;There was an attempt to &lt;a href=&#34;https://github.com/alephdata/aleph/issues/2127&#34;&gt;improve the way ingest-files manages the pending tasks&lt;/a&gt;, it&#39;s merged into the &lt;a href=&#34;https://github.com/alephdata/ingest-file/tree/release/4.0.0&#34;&gt;release/4.0.0&lt;/a&gt; branch, but it has &lt;a href=&#34;https://github.com/alephdata/ingest-file/pull/423&#34;&gt;not yet arrived &lt;code&gt;main&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;There are some tickets that attempt to address these issues on the command line:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/alephdata/alephclient/issues/34&#34;&gt;Allow users to upload/crawl new files only&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/alephdata/alephclient/issues/35&#34;&gt;Check if alephclient crawldir was 100% successful or not&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;I think it&#39;s interesting either to contribute to &lt;code&gt;alephclient&lt;/code&gt; to solve those issues or if it&#39;s complicated create a small python script to detect which files were not uploaded and try to reindex them and/or open issues that will prevent future ingests to fail.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;gitsigns&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gitsigns/&#34;&gt;gitsigns&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce gitsigns.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/lewis6991/gitsigns.nvim&#34;&gt;Gitsigns&lt;/a&gt; is a neovim plugin to create git decorations similar to the vim plugin &lt;a href=&#34;https://github.com/airblade/vim-gitgutter&#34;&gt;gitgutter&lt;/a&gt; but written purely in Lua.&lt;/p&gt; &lt;p&gt;Installation:&lt;/p&gt; &lt;p&gt;Add to your &lt;code&gt;plugins.lua&lt;/code&gt; file:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;  &lt;span class=&#34;n&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;lewis6991/gitsigns.nvim&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Install it with &lt;code&gt;:PackerInstall&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Configure it in your &lt;code&gt;init.lua&lt;/code&gt; with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;c1&#34;&gt;-- Configure gitsigns&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;gitsigns&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;on_attach&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bufnr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gs&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;package.loaded&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gitsigns&lt;/span&gt;

    &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;l&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;opts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;opts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;opts&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;opts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;bufnr&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;l&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;opts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;-- Navigation&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;]c&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
      &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;diff&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;]c&#39;&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;schedule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next_hunk&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
      &lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;Ignore&amp;gt;&#39;&lt;/span&gt;
    &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;[c&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
      &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;diff&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;[c&#39;&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;schedule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev_hunk&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
      &lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;Ignore&amp;gt;&#39;&lt;/span&gt;
    &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;-- Actions&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;gs&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stage_hunk&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;gr&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;reset_hunk&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;v&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;gs&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stage_hunk&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;line&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;.&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;line&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;v&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)}&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;v&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;gr&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;reset_hunk&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;line&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;.&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;line&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;v&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)}&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;gS&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stage_buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;gu&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;undo_stage_hunk&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;gR&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;reset_buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;gp&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;preview_hunk&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;gb&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;blame_line&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;full&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;gb&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;toggle_current_line_blame&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;gd&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;diffthis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;gD&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;diffthis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;~&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;ge&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;toggle_deleted&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;-- Text object&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;o&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;x&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;ih&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;:&amp;lt;C-U&amp;gt;Gitsigns select_hunk&amp;lt;CR&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Usage:&lt;/p&gt; &lt;p&gt;Some interesting bindings:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;]c&lt;/code&gt;: Go to next diff chunk&lt;/li&gt; &lt;li&gt;&lt;code&gt;[c&lt;/code&gt;: Go to previous diff chunk&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;leader&amp;gt;gs&lt;/code&gt;: Stage chunk, it works both in normal and visual mode&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;leader&amp;gt;gr&lt;/code&gt;: Restore chunk from index, it works both in normal and visual mode&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;leader&amp;gt;gp&lt;/code&gt;: Preview diff, you can use it with &lt;code&gt;]c&lt;/code&gt; and &lt;code&gt;[c&lt;/code&gt; to see all the chunk diffs&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;leader&amp;gt;gb&lt;/code&gt;: Show the git blame of the line as a shadowed comment&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;diffview&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/diffview/&#34;&gt;Diffview&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce DiffView.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/sindrets/diffview.nvim&#34;&gt;Diffview&lt;/a&gt; is a single tabpage interface for easily cycling through diffs for all modified files for any git rev.&lt;/p&gt; &lt;p&gt;Installation:&lt;/p&gt; &lt;p&gt;If you&#39;re using it with NeoGit and Packer use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;  &lt;span class=&#34;n&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s1&#34;&gt;&#39;NeogitOrg/neogit&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;requires&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;s1&#34;&gt;&#39;nvim-lua/plenary.nvim&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s1&#34;&gt;&#39;sindrets/diffview.nvim&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;s1&#34;&gt;&#39;nvim-tree/nvim-web-devicons&#39;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Usage:&lt;/p&gt; &lt;p&gt;Calling &lt;code&gt;:DiffviewOpen&lt;/code&gt; with no args opens a new &lt;code&gt;Diffview&lt;/code&gt; that compares against the current index. You can also provide any valid git rev to view only changes for that rev.&lt;/p&gt; &lt;p&gt;Examples:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;:DiffviewOpen&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;:DiffviewOpen HEAD~2&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;:DiffviewOpen HEAD~4..HEAD~2&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;:DiffviewOpen d4a7b0d&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;:DiffviewOpen d4a7b0d^!&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;:DiffviewOpen d4a7b0d..519b30e&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;:DiffviewOpen origin/main...HEAD&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;You can also provide additional paths to narrow down what files are shown &lt;code&gt;:DiffviewOpen HEAD~2 -- lua/diffview plugin&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Additional commands for convenience:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;:DiffviewClose&lt;/code&gt;: Close the current diffview. You can also use &lt;code&gt;:tabclose&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;&lt;code&gt;:DiffviewToggleFiles&lt;/code&gt;: Toggle the file panel.&lt;/li&gt; &lt;li&gt;&lt;code&gt;:DiffviewFocusFiles&lt;/code&gt;: Bring focus to the file panel.&lt;/li&gt; &lt;li&gt;&lt;code&gt;:DiffviewRefresh&lt;/code&gt;: Update stats and entries in the file list of the current Diffview.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;With a Diffview open and the default key bindings, you can:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Cycle through changed files with &lt;code&gt;&amp;lt;tab&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;s-tab&amp;gt;&lt;/code&gt;&lt;/li&gt; &lt;li&gt;You can stage changes with &lt;code&gt;-&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Restore a file with &lt;code&gt;X&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Refresh the diffs with &lt;code&gt;R&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Go to the file panel with &lt;code&gt;&amp;lt;leader&amp;gt;e&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/diffview/#use-the-same-binding-to-open-and-close-the-diffview-windows&#34;&gt;Use the same binding to open and close the diffview windows.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;dv&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;diffview.lib&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;views&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;DiffviewOpen&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;kr&#34;&gt;else&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;DiffviewClose&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;beets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/tridactyl/&#34;&gt;Beets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce tridactyl.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/tridactyl/tridactyl&#34;&gt;Tridactyl&lt;/a&gt; is a Vim-like interface for Firefox, inspired by Vimperator/Pentadactyl.&lt;/p&gt; &lt;p&gt;In the article you&#39;ll also find:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/tridactyl/#select-text-from-the-page&#34;&gt;How to select text on the page&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Guide on how to start using it.&lt;/p&gt; &lt;p&gt;You’ll want to set a few basic options before you start using beets. The &lt;a href=&#34;https://beets.readthedocs.io/en/stable/reference/config.html&#34;&gt;configuration&lt;/a&gt; is stored in a text file. You can show its location by running &lt;code&gt;beet config -p&lt;/code&gt;, though it may not exist yet. Run &lt;code&gt;beet config -e&lt;/code&gt; to edit the configuration in your favorite text editor. The file will start out empty, but here’s good place to start:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;~/music&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;library&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;~/data/musiclibrary.db&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The default configuration assumes you want to start a new organized music folder (that directory above) and that you’ll copy cleaned-up music into that empty folder using beets’ &lt;code&gt;import&lt;/code&gt; command. But you can configure beets to behave many other ways:&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Start with a new empty directory, but move new music in instead of copying it (saving disk space). Put this in your config file:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;import&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;move&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Keep your current directory structure; importing should never move or copy files but instead just correct the tags on music. Put the line &lt;code&gt;copy: no&lt;/code&gt; under the &lt;code&gt;import:&lt;/code&gt; heading in your config file to disable any copying or renaming. Make sure to point &lt;code&gt;directory&lt;/code&gt; at the place where your music is currently stored.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Keep your current directory structure and do not correct files’ tags: leave files completely unmodified on your disk. (Corrected tags will still be stored in beets’ database, and you can use them to do renaming or tag changes later.) Put this in your config file:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;import&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;copy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;no&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;no&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;to disable renaming and tag-writing.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/beets/#importing-your-library&#34;&gt;Importing your library.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The next step is to import your music files into the beets library database. Because this can involve modifying files and moving them around, data loss is always a possibility, so now would be a good time to make sure you have a recent backup of all your music. We’ll wait.&lt;/p&gt; &lt;p&gt;There are two good ways to bring your existing library into beets. You can either: (a) quickly bring all your files with all their current metadata into beets’ database, or (b) use beets’ highly-refined autotagger to find canonical metadata for every album you import. Option (a) is really fast, but option (b) makes sure all your songs’ tags are exactly right from the get-go. The point about speed bears repeating: using the autotagger on a large library can take a very long time, and it’s an interactive process. So set aside a good chunk of time if you’re going to go that route.&lt;/p&gt; &lt;p&gt;If you’ve got time and want to tag all your music right once and for all, do this:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;beet&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;import&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/path/to/my/music
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;(Note that by default, this command will copy music into the directory you specified above. If you want to use your current directory structure, set the import.copy config option.) To take the fast, un-autotagged path, just say:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;beet&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;import&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-A&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/my/huge/mp3/library
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Note that you just need to add &lt;code&gt;-A&lt;/code&gt; for “don’t autotag”.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;gancio&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gancio/&#34;&gt;Gancio&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Gancio.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://gancio.org/&#34;&gt;Gancio&lt;/a&gt; is a shared agenda for local communities.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://gancio.org/&#34;&gt;Docs&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://framagit.org/les/gancio&#34;&gt;Source&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://gancio.org/&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://framagit.org/bcn.convocala/gancio-plugin-telegram-bridge&#34;&gt;Telegram bridge&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gancio/#references&#34;&gt;Add radar squat.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://radar.squat.net&#34;&gt;https://radar.squat.net&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;google-chrome&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/google_chrome/&#34;&gt;google chrome&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Update the installation steps.&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Import the GPG key, and use the following command. &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wget&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-O-&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://dl.google.com/linux/linux_signing_key.pub&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;gpg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--dearmor&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/usr/share/keyrings/google-chrome.gpg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Once the GPG import is complete, you will need to import the Google Chrome repository.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome.gpg] http://dl.google.com/linux/chrome/deb/ stable main&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tee&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/apt/sources.list.d/google-chrome.list
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Install the program: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update
apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;google-chrome-stable
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;gotify&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gotify/&#34;&gt;Gotify&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce gotify.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/gotify/server&#34;&gt;Gotify&lt;/a&gt; is a simple server for sending and receiving messages in real-time per WebSocket.&lt;/p&gt; &lt;p&gt;Not there yet:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/gotify/server/issues/494&#34;&gt;Reactions on the notifications&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;hard-drive-health&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/hard_drive_health/&#34;&gt;Hard drive health&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/hard_drive_health/#check-the-health-of-a-disk-with-smartctl&#34;&gt;Check the disk health with smartctl.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Start with a long self test with &lt;code&gt;smartctl&lt;/code&gt;. Assuming the disk to test is &lt;code&gt;/dev/sdd&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;smartctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;long&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The command will respond with an estimate of how long it thinks the test will take to complete.&lt;/p&gt; &lt;p&gt;To check progress use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;smartctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-A&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;remaining
smartctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;remaining
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Don&#39;t check too often because it can abort the test with some drives. If you receive an empty output, examine the reported status with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;smartctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;selftest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If errors are shown, check the &lt;code&gt;dmesg&lt;/code&gt; as there are usually useful traces of the error.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/hard_drive_health/#check-the-health-of-a-disk-with-badblocks&#34;&gt;Check the health of a disk with badblocks.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The &lt;code&gt;badblocks&lt;/code&gt; command will write and read the disk with different patterns, thus overwriting the whole disk, so you will loose all the data in the disk.&lt;/p&gt; &lt;p&gt;This test is good for rotational disks as there is no disk degradation on massive writes, do not use it on SSD though.&lt;/p&gt; &lt;p&gt;WARNING: be sure that you specify the correct disk!!&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;badblocks&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-wsv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-b&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4096&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sde&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tee&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;disk_analysis_log.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If errors are shown is that all of the spare sectors of the disk are used, so you must not use this disk anymore. Again, check &lt;code&gt;dmesg&lt;/code&gt; for traces of disk errors.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;i3wm&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/i3wm/&#34;&gt;i3wm&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/i3wm/#move-the-focus-to-a-container&#34;&gt;Move the focus to a container.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Get the container identifier with &lt;code&gt;xprop&lt;/code&gt; and then:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;i3-msg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;[title=&#34;khime&#34;]&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;focus
i3-msg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;[class=&#34;Firefox&#34;]&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;focus
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/i3wm/#interact-with-python&#34;&gt;Interact with Python.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Install the &lt;code&gt;i3ipc&lt;/code&gt; library:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;i3ipc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Create the connection object:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;i3ipc&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Connection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Event&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;i3&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Connection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Interact with i3:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;focused&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_tree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;find_focused&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Focused window &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%s&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt; is on workspace &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%s&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;focused&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;focused&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;workspace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;outputs&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_outputs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Active outputs:&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;output&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;filter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;active&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;outputs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;output&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;i3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;focus left&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;container&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_tree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;find_fullscreen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;container&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;fullscreen&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;root&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_tree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;root&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;con&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;root&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;con&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;on_workspace_focus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;# The first parameter is the connection to the ipc and the second is an object&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;# with the data of the event sent from i3.&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Windows on this workspace:&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;w&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;leaves&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;w&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;on_window_focus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;focused&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_tree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;find_focused&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;ws_name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%s&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%s&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;focused&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;workspace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;num&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;focused&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;window_class&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;i3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;rename workspace to &#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%s&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#34;&#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ws_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;i3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Event&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WORKSPACE_FOCUS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;on_workspace_focus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;i3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Event&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WINDOW_FOCUS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;on_window_focus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;i3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;jellyfin&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/&#34;&gt;Jellyfin&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/#corrupt:-sqlitepcl.pretty.sqliteexception:-database-disk-image-is-malformed&#34;&gt;Fix Corrupt: SQLitePCL.pretty.SQLiteException: database disk image is malformed.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If your server log file shows SQLite errors like the following example your jellyfin.db file needs attention.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&#39;SQLitePCL.pretty.SQLiteException&#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Typical causes of this are sudden and abrupt terminations of the Emby server process, such as a power loss, operating system crash, force killing the server process, etc.&lt;/p&gt; &lt;p&gt;To solve it there are many steps:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/#remove-database-locks&#34;&gt;Remove Database Locks&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/#check-database-integrity-and-recover-database&#34;&gt;Check Database Integrity and Recover Database&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/#reset-library-database-&amp;amp;-load-fresh&#34;&gt;Reset Library Database &amp;amp; Load Fresh&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/#restore-watched-history&#34;&gt;Restore watched history.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Jellyfin stores the watched information in one of the &lt;code&gt;.db&lt;/code&gt; files, there are two ways to restore it:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Using scripts that interact with the API like &lt;a href=&#34;https://github.com/mueslimak3r/jelly-jar&#34;&gt;&lt;code&gt;jelly-jar&lt;/code&gt;&lt;/a&gt; or &lt;a href=&#34;https://github.com/jab416171/jellyfin-backup-watched&#34;&gt;&lt;code&gt;jellyfin-backup-watched&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Running sqlite queries on the database itself.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The user data is stored in the table &lt;code&gt;UserDatas&lt;/code&gt; table in the &lt;code&gt;library.db&lt;/code&gt; database file. The media data is stored in the &lt;code&gt;TypedBaseItems&lt;/code&gt; table of the same database.&lt;/p&gt; &lt;p&gt;Comparing the contents of the tables of the broken database (lost watched content) and a backup database, I&#39;ve seen that the media content is the same after a full library rescan, so the issue was fixed after injecting the missing user data from the backup to the working database through the &lt;a href=&#34;https://lyz-code.github.io/blue-book/sqlite/#import-a-table-from-another-database&#34;&gt;importing a table from another database&lt;/a&gt; sqlite operation.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/#readonly:-sqlitepcl.pretty.sqliteexception:-attempt-to-write-a-readonly-database&#34;&gt;Fix ReadOnly: SQLitePCL.pretty.SQLiteException: attempt to write a readonly database.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Some of the database files of Jellyfin is not writable by the jellyfin user, check if you changed the ownership of the files, for example in the process of restoring a database file from backup.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/#deceptive-site-ahead&#34;&gt;Deceptive site ahead.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It seems that Google is marking the domains that host Jellyfin as deceptive. If it happens to you, your users won&#39;t be able to access your instance with Firefox, Chrome nor the Android app. Nice uh? It&#39;s kind of scary how google is able to control who can access what in the internet without you signing for it.&lt;/p&gt; &lt;p&gt;If you search the problem online they suggest that you log in with your google account into the Search Console and see the reasons behind it. Many people did this and reported in the issue that they didn&#39;t get any useful information through this process. It&#39;s a privacy violation though, as now google is able to tie your identity (as your google account is linked to your phone number) with your Jellyfin domain. Completely disgusting.&lt;/p&gt; &lt;p&gt;To solve this issue you need &lt;a href=&#34;https://safebrowsing.google.com/safebrowsing/report_error/?tpl=mozilla&amp;amp;hl=en&#34;&gt;to file a case with google&lt;/a&gt; and wait for them to unban you. It&#39;s like asking them for permission so that they let your users access your system. The disgust levels keep on growing. Don&#39;t waste your time being creative in the Comments of the request either, it looks like they don&#39;t even read them.&lt;/p&gt; &lt;p&gt;The problem is that until the people from Jellyfin finds a solution, after following this ugly process, you may be flagged again any time in the future (ranging from days to months).&lt;/p&gt; &lt;p&gt;A mitigation of the problem is to have an alternative domain that your users can use (for example in duckdns.org). You may be lucky that google doesn&#39;t block both domains at the same time.&lt;/p&gt; &lt;p&gt;For more information follow the &lt;a href=&#34;https://github.com/jellyfin/jellyfin-web/issues/4076&#34;&gt;Jellyfin issue&lt;/a&gt; or the &lt;a href=&#34;https://www.reddit.com/r/jellyfin/comments/xqk01i/deceptive_site_ahead/&#34;&gt;Jellyfin reddit thread&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/#missing-features&#34;&gt;Missing features.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Hide movie or tv show from my gallery: Tracked by these feature requests &lt;a href=&#34;https://features.jellyfin.org/posts/1072/let-the-user-hide-a-movie-or-tv-show&#34;&gt;1&lt;/a&gt; and &lt;a href=&#34;https://features.jellyfin.org/posts/116/add-hide-ignore-for-series-seasons-episodes-as-an-alternative-to-favorite&#34;&gt;2&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/#jellyfin-desktop&#34;&gt;Introduce Jellyfin Desktop.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Download the latest deb package from the &lt;a href=&#34;https://github.com/jellyfin/jellyfin-media-player/releases&#34;&gt;releases page&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Install the dependencies&lt;/li&gt; &lt;li&gt;Run &lt;code&gt;dpkg -i&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;If you&#39;re on a TV you may want to &lt;a href=&#34;https://github.com/jellyfin/jellyfin-media-player/issues/11&#34;&gt;enable the TV mode&lt;/a&gt; so that the remote keys work as expected. The play/pause/next/prev won&#39;t work until &lt;a href=&#34;https://github.com/jellyfin/jellyfin-media-player/issues/3&#34;&gt;this issue is solved&lt;/a&gt;, but it&#39;s not that bad to use the &#34;Ok&#34; and then navigate with the arrow keys.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/#jellycon&#34;&gt;Introduce Jellycon.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;JellyCon is a lightweight Kodi add-on that lets you browse and play media files directly from your Jellyfin server within the Kodi interface. It can be thought of as a thin frontend for a Jellyfin server.&lt;/p&gt; &lt;p&gt;It&#39;s not very pleasant to use though.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/#forgot-password.-please-try-again-within-your-home-network-to-initiate-the-password-reset-process.&#34;&gt;Forgot Password. Please try again within your home network to initiate the password reset process.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you&#39;re an external jellyfin user you can&#39;t reset your password unless you are part of the LAN. This is done because the reset password process is simple and insecure.&lt;/p&gt; &lt;p&gt;If you don&#39;t care about that and still think that the internet is a happy and safe place &lt;a href=&#34;https://wiki.jfa-go.com/docs/password-resets/&#34;&gt;here&lt;/a&gt; and &lt;a href=&#34;https://github.com/hrfee/jellyfin-accounts/issues/12&#34;&gt;here&lt;/a&gt; are some instructions on how to bypass the security measure.&lt;/p&gt; &lt;p&gt;For more information also read &lt;a href=&#34;https://github.com/jellyfin/jellyfin/issues/2282&#34;&gt;1&lt;/a&gt; and &lt;a href=&#34;https://github.com/jellyfin/jellyfin/issues/2869&#34;&gt;2&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;kitty&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/kitty/&#34;&gt;Kitty&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/kitty/#fonts&#34;&gt;How to add fonts to kitty.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Add your fonts to the &lt;code&gt;~/.local/share/fonts&lt;/code&gt; directory&lt;/li&gt; &lt;li&gt;Check they are available when you run &lt;code&gt;kitty +list-fonts&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Add them to your config:&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;font_family      Operator Mono Book
bold_font        Operator Mono Medium
italic_font      Operator Mono Book Italic
bold_italic_font Operator Mono Medium Italic
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; feat(kitty#Screen not working on server with sudo): Troubleshoot the Screen not working on server with sudo issue&lt;/p&gt; &lt;p&gt;Make sure you&#39;re using the ssh alias below&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;alias&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ssh&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;kitty +kitten ssh&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;And then copy the &lt;code&gt;~/.terminfo&lt;/code&gt; into &lt;code&gt;/root&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;copy&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;~/.terminfo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/root
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;kodi&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/kodi/&#34;&gt;Kodi&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Kodi.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://kodi.tv/&#34;&gt;Kodi&lt;/a&gt; is a entertainment center software. It basically converts your device into a smart tv&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;koel&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/koel/&#34;&gt;Koel&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Koel.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://koel.dev/&#34;&gt;koel&lt;/a&gt; is a personal music streaming server.&lt;/p&gt; &lt;p&gt;Note: Use &lt;a href=&#34;https://lyz-code.github.io/blue-book/mopidy/&#34;&gt;&lt;code&gt;mopidy&lt;/code&gt;&lt;/a&gt; instead&lt;/p&gt; &lt;p&gt;There are &lt;a href=&#34;https://github.com/koel/docker&#34;&gt;docker-compose files&lt;/a&gt; to host the service. Although they behave a little bit weird&lt;/p&gt; &lt;p&gt;For example, you need to &lt;a href=&#34;https://github.com/koel/docker/issues/168&#34;&gt;specify the DB_PORT&lt;/a&gt;. It has had several PR to fix it but weren&#39;t merged &lt;a href=&#34;https://github.com/koel/docker/pull/165/files&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;https://github.com/koel/docker/pull/162/files&#34;&gt;2&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;The API is &lt;a href=&#34;https://github.com/koel/koel/issues/535&#34;&gt;not very well documented&lt;/a&gt;:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/X-Ryl669/kutr/wiki/Communication-API#authentication&#34;&gt;Here you can see how to authenticate&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/koel/koel/blob/master/api-docs/api.yaml#L763&#34;&gt;Here are the api docs&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;matrix&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/matrix/&#34;&gt;Matrix&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: How to install matrix.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-y&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wget&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-transport-https
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wget&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-O&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/usr/share/keyrings/element-io-archive-keyring.gpg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://packages.element.io/debian/element-io-archive-keyring.gpg
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;deb [signed-by=/usr/share/keyrings/element-io-archive-keyring.gpg] https://packages.element.io/debian/ default main&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tee&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/apt/sources.list.d/element-io.list
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;element-desktop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;mediatracker&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/mediatracker/&#34;&gt;Mediatracker&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce MediaTracker.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/bonukai/MediaTracker&#34;&gt;MediaTracker&lt;/a&gt; is a self hosted media tracker for movies, tv shows, video games, books and audiobooks&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/bonukai/MediaTracker#installation&#34;&gt;Installation&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;With docker compose:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;3&#34;&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;mediatracker&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;container_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;mediatracker&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ports&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;7481:7481&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/home/YOUR_HOME_DIRECTORY/.config/mediatracker/data:/storage&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;assetsVolume:/assets&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;environment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;SERVER_LANG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;en&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;TMDB_LANG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;en&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;AUDIBLE_LANG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;us&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;TZ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Europe/London&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;bonukai/mediatracker:latest&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;assetsVolume&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;null&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you attach more than one docker network the container becomes unreachable :S.&lt;/p&gt; &lt;p&gt;Install the jellyfin plugin:&lt;/p&gt; &lt;p&gt;They created a &lt;a href=&#34;https://github.com/bonukai/jellyfin-plugin-mediatracker&#34;&gt;Jellyfin plugin&lt;/a&gt; so that all scrobs are sent automatically to the mediatracker&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Add new Repository in Jellyfin (Dashboard -&amp;gt; Plugins -&amp;gt; Repositories -&amp;gt; +) from url &lt;code&gt;https://raw.githubusercontent.com/bonukai/jellyfin-plugin-mediatracker/main/manifest.json&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Install MediaTracker plugin from Catalogue (Dashboard -&amp;gt; Plugins -&amp;gt; Catalogue)&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Some tips on usage:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Add the shows you want to watch to the watchlist so that it&#39;s easier to find them&lt;/li&gt; &lt;li&gt; &lt;p&gt;When you&#39;re ending an episode, click on the episode number on the watchlist element and then rate the episode itself.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;You can create public lists to share with the rest of the users, the way to share it though &lt;a href=&#34;https://github.com/bonukai/MediaTracker/issues/527&#34;&gt;is a bit archaic so far&lt;/a&gt;, it&#39;s only through the list link, in the interface they won&#39;t be able to see it.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/mediatracker/#alternatives&#34;&gt;Update ryot comparison with mediatracker.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/IgnisDa/ryot&#34;&gt;Ryot&lt;/a&gt; has a better web design, it also has a &lt;a href=&#34;https://github.com/IgnisDa/ryot/pull/195&#34;&gt;jellyfin scrobbler&lt;/a&gt;, although it&#39;s not &lt;a href=&#34;https://github.com/IgnisDa/ryot/issues/187&#34;&gt;yet stable&lt;/a&gt;. There are other UI tweaks that is preventing me from migrating to ryot such as &lt;a href=&#34;https://github.com/IgnisDa/ryot/issues/284&#34;&gt;the easier media rating&lt;/a&gt; and &lt;a href=&#34;https://github.com/IgnisDa/ryot/issues/283&#34;&gt;the percentage over five starts rating system&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;retroarch&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/retroarch/&#34;&gt;retroarch&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Install retroarch instructions.&lt;/p&gt; &lt;p&gt;To add the stable branch to your system type:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;add-apt-repository&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ppa:libretro/stable
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;retroarch
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Go to Main Menu/Online Updater and then update everything you can:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Update Core Info Files&lt;/li&gt; &lt;li&gt;Update Assets&lt;/li&gt; &lt;li&gt;Update controller Profiles&lt;/li&gt; &lt;li&gt;Update Databases&lt;/li&gt; &lt;li&gt;Update Overlays&lt;/li&gt; &lt;li&gt;Update GLSL Shaders&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;rocketchat&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/rocketchat/&#34;&gt;Rocketchat&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Rocketchat integrations.&lt;/p&gt; &lt;p&gt;Rocket.Chat supports webhooks to integrate tools and services you like into the platform. Webhooks are simple event notifications via HTTP POST. This way, any webhook application can post a message to a Rocket.Chat instance and much more.&lt;/p&gt; &lt;p&gt;With scripts, you can point any webhook to Rocket.Chat and process the requests to print customized messages, define the username and avatar of the user of the messages and change the channel for sending messages, or you can cancel the request to prevent undesired messages.&lt;/p&gt; &lt;p&gt;Available integrations:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Incoming Webhook: Let an external service send a request to Rocket.Chat to be processed.&lt;/li&gt; &lt;li&gt;Outgoing Webhook: Let Rocket.Chat trigger and optionally send a request to an external service and process the response.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;By default, a webhook is designed to post messages only. The message is part of a JSON structure, which has the same format as that of a .&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://docs.rocket.chat/use-rocket.chat/workspace-administration/integrations#incoming-webhook-script&#34;&gt;Incoming webhook script&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;To create a new incoming webhook:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Navigate to Administration &amp;gt; Workspace &amp;gt; Integrations.&lt;/li&gt; &lt;li&gt;Click +New at the top right corner.&lt;/li&gt; &lt;li&gt;Switch to the Incoming tab.&lt;/li&gt; &lt;li&gt;Turn on the Enabled toggle.&lt;/li&gt; &lt;li&gt;Name: Enter a name for your webhook. The name is optional; however, providing a name to manage your integrations easily is advisable.&lt;/li&gt; &lt;li&gt;Post to Channel: Select the channel (or user) where you prefer to receive the alerts. It is possible to override messages.&lt;/li&gt; &lt;li&gt;Post as: Choose the username that this integration posts as. The user must already exist.&lt;/li&gt; &lt;li&gt;Alias: Optionally enter a nickname that appears before the username in messages.&lt;/li&gt; &lt;li&gt;Avatar URL: Enter a link to an image as the avatar URL if you have one. The avatar URL overrides the default avatar.&lt;/li&gt; &lt;li&gt;Emoji: Enter an emoji optionally to use the emoji as the avatar. &lt;a href=&#34;https://github.com/ikatyang/emoji-cheat-sheet/blob/master/README.md#computer&#34;&gt;Check the emoji cheat sheet&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Turn on the Script Enabled toggle.&lt;/li&gt; &lt;li&gt;Paste your script inside the Script field (check below for a sample script)&lt;/li&gt; &lt;li&gt;Save the integration.&lt;/li&gt; &lt;li&gt;Use the generated Webhook URL to post messages to Rocket.Chat.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The Rocket.Chat integration script should be written in ES2015 / ECMAScript 6. The script requires a global class named Script, which is instantiated only once during the first execution and kept in memory. This class contains a method called &lt;code&gt;process_incoming_request&lt;/code&gt;, which is called by your server each time it receives a new request. The &lt;code&gt;process_incoming_request&lt;/code&gt; method takes an object as a parameter with the request property and returns an object with a content property containing a valid Rocket.Chat message, or an object with an error property, which is returned as the response to the request in JSON format with a Code 400 status.&lt;/p&gt; &lt;p&gt;A valid Rocket.Chat message must contain a text field that serves as the body of the message. If you redirect the message to a channel other than the one indicated by the webhook token, you can specify a channel field that accepts room id or, if prefixed with &#34;#&#34; or &#34;@&#34;, channel name or user, respectively.&lt;/p&gt; &lt;p&gt;You can use the console methods to log information to help debug your script. More information about the console can be found &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/API/Console/log&#34;&gt;here&lt;/a&gt;. . To view the logs, navigate to Administration &amp;gt; Workspace &amp;gt; View Logs.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;/* exported Script */
/* globals console, _, s */

/** Global Helpers
 *
 * console - A normal console instance
 * _       - An underscore instance
 * s       - An underscore string instance
 */

class Script {
  /**
   * @params {object} request
   */
  process_incoming_request({ request }) {
    // request.url.hash
    // request.url.search
    // request.url.query
    // request.url.pathname
    // request.url.path
    // request.url_raw
    // request.url_params
    // request.headers
    // request.user._id
    // request.user.name
    // request.user.username
    // request.content_raw
    // request.content

    // console is a global helper to improve debug
    console.log(request.content);

    return {
      content:{
        text: request.content.text,
        icon_emoji: request.content.icon_emoji,
        channel: request.content.channel,
        // &#34;attachments&#34;: [{
        //   &#34;color&#34;: &#34;#FF0000&#34;,
        //   &#34;author_name&#34;: &#34;Rocket.Cat&#34;,
        //   &#34;author_link&#34;: &#34;https://open.rocket.chat/direct/rocket.cat&#34;,
        //   &#34;author_icon&#34;: &#34;https://open.rocket.chat/avatar/rocket.cat.jpg&#34;,
        //   &#34;title&#34;: &#34;Rocket.Chat&#34;,
        //   &#34;title_link&#34;: &#34;https://rocket.chat&#34;,
        //   &#34;text&#34;: &#34;Rocket.Chat, the best open source chat&#34;,
        //   &#34;fields&#34;: [{
        //     &#34;title&#34;: &#34;Priority&#34;,
        //     &#34;value&#34;: &#34;High&#34;,
        //     &#34;short&#34;: false
        //   }],
        //   &#34;image_url&#34;: &#34;https://rocket.chat/images/mockup.png&#34;,
        //   &#34;thumb_url&#34;: &#34;https://rocket.chat/images/mockup.png&#34;
        // }]
       }
    };

    // return {
    //   error: {
    //     success: false,
    //     message: &#39;Error example&#39;
    //   }
    // };
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To test if your integration works, use curl to make a POST request to the generated webhook URL.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-X&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;POST&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-H&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Content-Type: application/json&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;--data&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;{&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;      &#34;icon_emoji&#34;: &#34;:smirk:&#34;,&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;      &#34;text&#34;: &#34;Example message&#34;&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;  }&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;https://your-webhook-url
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you want to send the message to another channel or user use the &lt;code&gt;channel&lt;/code&gt; argument with &lt;code&gt;@user&lt;/code&gt; or &lt;code&gt;#channel&lt;/code&gt;. Keep in mind that the user of the integration needs to be part of those channels if they are private.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-X&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;POST&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-H&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Content-Type: application/json&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;--data&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;{&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;      &#34;icon_emoji&#34;: &#34;:smirk:&#34;,&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;      &#34;channel&#34;: &#34;#notifications&#34;,&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;      &#34;text&#34;: &#34;Example message&#34;&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;  }&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;https://your-webhook-url
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you want to do more complex things uncomment the part of the attachments.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;sed&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/sed/&#34;&gt;sed&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Introduce sed snippets.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;tails&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/tails/&#34;&gt;Tails&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add interesting operations on tails.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://tails.net/upgrade/tails/index.en.html&#34;&gt;Upgrading a tails USB&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.reddit.com/r/tails/comments/qzruhv/changing_window_manager/&#34;&gt;Change the window manager&lt;/a&gt;: Don&#39;t do it, they say it it will break Tails although I don&#39;t understand why&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;vdirsyncer&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vdirsyncer/&#34;&gt;vdirsyncer&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Use SHA256 for the verification.&lt;/p&gt; &lt;p&gt;Now SHA1 is not allowed&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Suggest more debuggin steps when connecting to google.&lt;/p&gt; &lt;p&gt;The code has changed and the fix is now different&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;vim&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/&#34;&gt;Vim&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/#configuration&#34;&gt;Configure nvim with lua.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Nvim moved away from vimscript and now needs to be configured in lua. You can access the config file in &lt;code&gt;~/.config/nvim/init.lua&lt;/code&gt;. It&#39;s not created by default so you need to do it yourself.&lt;/p&gt; &lt;p&gt;In the article it explains how to do the basic configuration with lua:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/#configuration&#34;&gt;Set variables&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/#key-bindings&#34;&gt;Set key bindings&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/#spelling&#34;&gt;Set spelling&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/#testing&#34;&gt;Set test runners&lt;/a&gt;: With &lt;code&gt;neotest&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/#buffer-and-file-management&#34;&gt;Set the buffer and file management&lt;/a&gt;: with &lt;code&gt;Telescope&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/#plugin-managers&#34;&gt;Use Plugin managers&lt;/a&gt;: it evaluates the different solutions and then explains how to install and use &lt;code&gt;packer&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/#treesitter&#34;&gt;What is and how to use &lt;code&gt;Treesitter&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/#git&#34;&gt;Set git integration&lt;/a&gt;: Evaluate the different solutions and configure &lt;code&gt;neogit&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/#run-lua-snippets&#34;&gt;How to run lua snippets&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;And some troubleshooting:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/#deal-with-big-files&#34;&gt;How to deal with big files and telescope&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/#the-leader-key&#34;&gt;Update the leader key section.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;There are different opinions on what key to use as the &lt;code&gt;&amp;lt;leader&amp;gt;&lt;/code&gt; key. The &lt;code&gt;&amp;lt;space&amp;gt;&lt;/code&gt; is the most comfortable as it&#39;s always close to your thumbs, and it works well with both hands. Nevertheless, you can only use it in normal mode, because in insert &lt;code&gt;&amp;lt;space&amp;gt;&amp;lt;whatever&amp;gt;&lt;/code&gt; will be triggered as you write. An alternative is to use &lt;code&gt;;&lt;/code&gt; which is also comfortable (if you use the english key distribution) and you can use it in insert mode.&lt;/p&gt; &lt;p&gt;If you &lt;a href=&#34;https://stackoverflow.com/questions/30467660/can-we-define-more-than-one-leader-key-in-vimrc&#34;&gt;want to define more than one leader key&lt;/a&gt; you can either:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Change the &lt;code&gt;mapleader&lt;/code&gt; many times in your file: As the value of &lt;code&gt;mapleader&lt;/code&gt; is used at the moment the mapping is defined, you can indeed change that while plugins are loading. For that, you have to explicitly &lt;code&gt;:runtime&lt;/code&gt; the plugins in your &lt;code&gt;~/.vimrc&lt;/code&gt; (and count on the canonical include guard to prevent redefinition later):&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;let&lt;/span&gt; mapleader &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;,&#39;&lt;/span&gt;
runtime&lt;span class=&#34;p&#34;&gt;!&lt;/span&gt; plugin/NERD_commenter.&lt;span class=&#34;k&#34;&gt;vim&lt;/span&gt;
runtime&lt;span class=&#34;p&#34;&gt;!&lt;/span&gt; ...
&lt;span class=&#34;k&#34;&gt;let&lt;/span&gt; mapleader &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;\&#39;&lt;/span&gt;
runime&lt;span class=&#34;p&#34;&gt;!&lt;/span&gt; plugin/mark.&lt;span class=&#34;k&#34;&gt;vim&lt;/span&gt;
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; * Use the keys directly instead of using &lt;code&gt;&amp;lt;leader&amp;gt;&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;c&#34;&gt;&#34; editing mappings&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;nnoremap&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;something&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;nnoremap&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;k&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;something &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;nnoremap&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;d&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;and something &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&#34;c&#34;&gt;&#34; window management mappings&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;nnoremap&lt;/span&gt; gw &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;something&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;nnoremap&lt;/span&gt; gb &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;something &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Defining &lt;code&gt;mapleader&lt;/code&gt; and/or using &lt;code&gt;&amp;lt;leader&amp;gt;&lt;/code&gt; may be useful if you change your mind often on what key to use a leader but it won&#39;t be of any use if your mappings are stable.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/#follow-symbolic-links&#34;&gt;Configure Telescope to follow symbolic links.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;By default symbolic links are not followed either for files or directories, to enable it use&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;  &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;telescope&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;pickers&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;find_files&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;follow&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/#run-a-command-when-opening-vim&#34;&gt;Run a command when opening vim.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;nvim&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;:DiffViewOpen&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Update treesitter language definitions.&lt;/p&gt; &lt;p&gt;To do so you need to run:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;TSInstall &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;language&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To update the parsers run&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;TSUpdate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/#telescope-changes-working-directory-when-opening-a-file&#34;&gt;Telescope changes working directory when opening a file.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;In my case was due to a snippet I have to remember the folds:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;vim.cmd[[
  augroup remember_folds
    autocmd!
    autocmd BufWinLeave * silent! mkview
    autocmd BufWinEnter * silent! loadview
  augroup END
]]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;It looks that it had saved a view with the other working directory so when a file was loaded the &lt;code&gt;cwd&lt;/code&gt; changed. To solve it I created a new &lt;code&gt;mkview&lt;/code&gt; in the correct directory.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/#concealment&#34;&gt;Concealment.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Some plugins allow the conceal of some text, for example in orgmode you will only see the text of the description of a link and not the content, making it more pleasant to read. To enable it set in your config:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;c1&#34;&gt;-- Conceal links&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;-- https://github.com/nvim-orgmode/orgmode#links-are-not-concealed&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;-- Use visual mode to navigate through the hidden text&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;opt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;conceallevel&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;opt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;concealcursor&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;nc&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where:&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;&lt;code&gt;conceallevel&lt;/code&gt;: Determine how text with the &#34;conceal&#34; syntax attribute is shown:&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;code&gt;0&lt;/code&gt;: Text is shown normally&lt;/p&gt; &lt;/li&gt; &lt;li&gt;&lt;code&gt;1&lt;/code&gt;: Each block of concealed text is replaced with one character. If the syntax item does not have a custom replacement character defined the character defined in &#39;listchars&#39; is used (default is a space). It is highlighted with the &#34;Conceal&#34; highlight group.&lt;/li&gt; &lt;li&gt;&lt;code&gt;2&lt;/code&gt;: Concealed text is completely hidden unless it has a custom replacement character defined.&lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;code&gt;3&lt;/code&gt;: Concealed text is completely hidden.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;code&gt;concealcursor&lt;/code&gt;: Sets the modes in which text in the cursor line can also be concealed. When the current mode is listed then concealing happens just like in other lines.&lt;/p&gt; &lt;/li&gt; &lt;li&gt;&lt;code&gt;n&lt;/code&gt;: Normal mode&lt;/li&gt; &lt;li&gt;&lt;code&gt;v&lt;/code&gt;: Visual mode&lt;/li&gt; &lt;li&gt;&lt;code&gt;i&lt;/code&gt;: Insert mode&lt;/li&gt; &lt;li&gt;&lt;code&gt;c&lt;/code&gt;: Command line editing, for &#39;incsearch&#39;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;A useful value is &lt;code&gt;nc&lt;/code&gt;. So long as you are moving around text is concealed, but when starting to insert text or selecting a Visual area the concealed text is displayed, so that you can see what you are doing.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/#email-inside-nvim&#34;&gt;Email inside nvim.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The best looking one is himalaya&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://pimalaya.org/himalaya/index.html&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://git.sr.ht/%7Esoywod/himalaya-vim&#34;&gt;Nvim plugin&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/soywod/himalaya&#34;&gt;Source&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;yq&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/yq/&#34;&gt;yq&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce yq.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/mikefarah/yq&#34;&gt;yq&lt;/a&gt; is a portable command-line YAML, JSON, XML, CSV, TOML and properties processor. It uses &lt;code&gt;jq&lt;/code&gt; like syntax but works with yaml files as well as json, xml, properties, csv and tsv. It doesn&#39;t yet support everything &lt;code&gt;jq&lt;/code&gt; does - but it does support the most common operations and functions, and more is being added continuously.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/yq/#find-and-update-items-in-an-array&#34;&gt;Find and update items in an array.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;We have an array and we want to update the elements with a particular name.&lt;/p&gt; &lt;p&gt;Given a &lt;code&gt;sample.yaml&lt;/code&gt; file of:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Foo&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;numBuckets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Bar&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;numBuckets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then &lt;code&gt;yq &#39;(.[] | select(.name == &#34;Foo&#34;) | .numBuckets) |= . + 1&#39; sample.yaml&lt;/code&gt; will output:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Foo&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;numBuckets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Bar&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;numBuckets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/yq/#iterate-over-the-elements-of-a-query-with-a-bash-loop&#34;&gt;Iterate over the elements of a query with a bash loop.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;readarray&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dependencies&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;yq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;e&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;j&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-I&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;.roles[]&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;requirements.yaml&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dependency&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;dependencies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$dependency&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;yq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;e&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;.src&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;android&#34;&gt;Android&lt;/h3&gt; &lt;h4 id=&#34;grapheneos&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/grapheneos/&#34;&gt;GrapheneOS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/grapheneos/#split-the-screen&#34;&gt;Split the screen.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Go into app switcher, tap on the app icon above the active app and then select &#34;Split top&#34;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;libretube&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/libretube/&#34;&gt;LibreTube&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Libretube.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/libre-tube/LibreTube&#34;&gt;Libretube&lt;/a&gt; is an alternative frontend for YouTube, for Android.&lt;/p&gt; &lt;p&gt;YouTube has an extremely invasive privacy policy which relies on using user data in unethical ways. They store a lot of your personal data - ranging from ideas, music taste, content, political opinions, and much more than you think.&lt;/p&gt; &lt;p&gt;This project is aimed at improving the users&#39; privacy by being independent from Google and bypassing their data collection.&lt;/p&gt; &lt;p&gt;Therefore, the app is using the &lt;a href=&#34;https://github.com/TeamPiped/Piped&#34;&gt;Piped API&lt;/a&gt;, which uses proxies to circumvent Google&#39;s data collection and includes some other additional features.&lt;/p&gt; &lt;p&gt;Differences to NewPipe:&lt;/p&gt; &lt;p&gt;With NewPipe, the extraction is done locally on your phone, and all the requests sent towards YouTube/Google are done directly from the network you&#39;re connected to, which doesn&#39;t use a middleman server in between. Therefore, Google can still access information such as the user&#39;s IP address. Aside from that, subscriptions can only be stored locally.&lt;/p&gt; &lt;p&gt;LibreTube takes this one step further and proxies all requests via Piped (which uses the NewPipeExtractor). This prevents Google servers from accessing your IP address or any other personal data. Apart from that, Piped allows syncing your subscriptions between LibreTube and Piped, which can be used on desktop too.&lt;/p&gt; &lt;p&gt;If the NewPipeExtractor breaks, it only requires an update of Piped and not LibreTube itself. Therefore, fixes usually arrive faster than in NewPipe.&lt;/p&gt; &lt;p&gt;While LibreTube only supports YouTube, NewPipe also allows the use of other platforms like SoundCloud, PeerTube, Bandcamp and media.ccc.de. Both are great clients for watching YouTube videos. It depends on the individual&#39;s use case which one fits their needs better.&lt;/p&gt; &lt;p&gt;Other software that uses Piped:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/yattee/yattee&#34;&gt;Yattee&lt;/a&gt; - an alternative frontend for YouTube, for IOS.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://codeberg.org/Hyperpipe/Hyperpipe&#34;&gt;Hyperpipe&lt;/a&gt; - an alternative privacy respecting frontend for YouTube Music.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/Bellisario/musicale&#34;&gt;Musicale&lt;/a&gt; - an alternative to YouTube Music, with style.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/n-ce/ytify&#34;&gt;ytify&lt;/a&gt; - a complementary minimal audio streaming frontend for YouTube.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/prateekmedia/pstube&#34;&gt;PsTube&lt;/a&gt; - Watch and download videos without ads on Android, Linux, Windows, iOS, and Mac OSX.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/mmjee/Piped-Material&#34;&gt;Piped-Material&lt;/a&gt; - A fork of Piped, focusing on better performance and a more usable design.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/NeeRaj-2401/ReacTube&#34;&gt;ReacTube&lt;/a&gt; - Privacy friendly &amp;amp; distraction free Youtube front-end using Piped API.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;happycow&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/happycow/&#34;&gt;HappyCow&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Happycow.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.happycow.net/&#34;&gt;Happycow&lt;/a&gt; is a web application and android app to search vegan restaurants nearby.&lt;/p&gt; &lt;p&gt;The android app requires google services to work :(.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;orgzly&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgzly/&#34;&gt;Orgzly&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Orgzly.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://orgzly.com/&#34;&gt;Orgzly&lt;/a&gt; is an android application to interact with &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/&#34;&gt;orgmode&lt;/a&gt; files.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgzly/#avoid-the-conflicts-in-the-files-edited-in-two-places&#34;&gt;Avoid the conflicts in the files edited in two places.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you use syncthing you may be seeing conflicts in your files. This happens specially if you use the Orgzly widget to add tasks, this is because it doesn&#39;t synchronize the files to the directory when using the widget. If you have a file that changes a lot in a device, for example the &lt;code&gt;inbox.org&lt;/code&gt; of my mobile, it&#39;s interesting to have a specific file that&#39;s edited mainly in the mobile, and when you want to edit it elsewhere, you sync as specified below and then process with the editing. Once it&#39;s done manually sync the changes in orgzly again. The rest of the files synced to the mobile are for read only reference, so they rarely change.&lt;/p&gt; &lt;p&gt;If you want to sync reducing the chance of conflicts then:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Open Orgzly and press Synchronize&lt;/li&gt; &lt;li&gt;Open Syncthing.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;If that&#39;s not enough &lt;a href=&#34;https://github.com/orgzly/orgzly-android/issues/8&#34;&gt;check these automated solutions&lt;/a&gt;:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://gist.github.com/fabian-thomas/6f559d0b0d26737cf173e41cdae5bfc8&#34;&gt;Orgzly auto syncronisation for sync tools like syncthing&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://gitlab.com/doak/orgzly-watcher/-/blob/master/watch-for-orgzly?ref_type=heads&#34;&gt;watch-for-orgzly&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Other interesting solutions:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://codeberg.org/anoduck/org-orgzly&#34;&gt;org-orgzly&lt;/a&gt;: Script to parse a chosen org file or files, check if an entry meets required parameters, and if it does, write the entry in a new file located inside the folder you desire to sync with orgzly.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/orgzly/orgzly-android/issues/24&#34;&gt;Git synchronization&lt;/a&gt;: I find it more cumbersome than syncthing but maybe it&#39;s interesting for you.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgzly/#references&#34;&gt;Add new orgzly fork.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/orgzly-revived/orgzly-android-revived&#34;&gt;Alternative fork maintained by the community&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;seedvault&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/seedvault/&#34;&gt;Seedvault&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce seedvault.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://calyxinstitute.org/projects/seedvault-encrypted-backup-for-android&#34;&gt;Seedvault&lt;/a&gt; is an open-source encrypted backup app for inclusion in Android-based operating systems.&lt;/p&gt; &lt;p&gt;While every smartphone user wants to be prepared with comprehensive data backups in case their phone is lost or stolen, not every Android user wants to entrust their sensitive data to Google&#39;s cloud-based storage. By storing data outside Google&#39;s reach, and by using client-side encryption to protect all backed-up data, Seedvault offers users maximum data privacy with minimal hassle.&lt;/p&gt; &lt;p&gt;Seedvault allows Android users to store their phone data without relying on Google&#39;s proprietary cloud storage. Users can decide where their phone&#39;s backup will be stored, with options ranging from a USB flash drive to a remote self-hosted cloud storage alternative such as NextCloud. Seedvault also offers an Auto-Restore feature: instead of permanently losing all data for an app when it is uninstalled, Seedvault&#39;s Auto-Restore will restore all backed-up data for the app upon reinstallation.&lt;/p&gt; &lt;p&gt;Seedvault protects users&#39; private data by encrypting it on the device with a key known only to the user. Each Seedvault account is protected by client-side encryption (AES/GCM/NoPadding). This encryption is unlockable only with a 12-word randomly-generated key.&lt;/p&gt; &lt;p&gt;With Seedvault, backups run automatically in the background of the phone&#39;s operating system, ensuring that no data will be left behind if the device is lost or stolen. The Seedvault application requires no technical knowledge to operate, and does not require a rooted device.&lt;/p&gt; &lt;p&gt;In the article you&#39;ll also find:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;How to install it&lt;/li&gt; &lt;li&gt;How to store the backup remotely&lt;/li&gt; &lt;li&gt;How to restore a backup&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;signal&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/signal/&#34;&gt;Signal&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add installation steps.&lt;/p&gt; &lt;p&gt;These instructions only work for 64 bit Debian-based Linux distributions such as Ubuntu, Mint etc.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Install our official public software signing key&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;wget&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-O-&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://updates.signal.org/desktop/apt/keys.asc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;gpg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--dearmor&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;signal-desktop-keyring.gpg
cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;signal-desktop-keyring.gpg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tee&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/usr/share/keyrings/signal-desktop-keyring.gpg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/null
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Add our repository to your list of repositories&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;deb [arch=amd64 signed-by=/usr/share/keyrings/signal-desktop-keyring.gpg] https://updates.signal.org/desktop/apt xenial main&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tee&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/apt/sources.list.d/signal-xenial.list
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Update your package database and install signal&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;signal-desktop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;arts&#34;&gt;Arts&lt;/h2&gt; &lt;h3 id=&#34;dancing&#34;&gt;Dancing&lt;/h3&gt; &lt;h4 id=&#34;shag&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/shag/&#34;&gt;Shag&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add awesome Shag videos.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Sandy Lewis and Martí Gasol:&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://yewtu.be/watch?v=CpaicCRacF0&#34;&gt;Warsaw Collegiate Shag Festival 2017&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://yewtu.be/watch?v=8iIEFtoro_Y&#34;&gt;Warsaw Collegiate Shag Festival 2016&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Cherry Moreno and Filip Gorski:&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://yewtu.be/watch?v=Rzi5MUYaRrM&#34;&gt;BCN Shag Festival 2018&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://yewtu.be/watch?v=Co94T2f3Pw4&#34;&gt;RTSF 2019&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Stephen and Chandrae:&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://yewtu.be/watch?v=dRQ-RsAXdEM&#34;&gt;Minor Swing&lt;/a&gt;&lt;/li&gt; &lt;li&gt;[RTSF 2013](&lt;a href=&#34;https://yewtu.be/watch?v=uUGsLoZYXb4&#34;&gt;https://yewtu.be/watch?v=uUGsLoZYXb4&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://yewtu.be/watch?v=krEtvtJMbxg&#34;&gt;RTSF 2016 with Arnas and Egle&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://yewtu.be/watch?v=pUt3_ybtxoU&#34;&gt;MBSW 2013&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Warsaw Shag team&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://yewtu.be/watch?v=QGJAIKyW7r4&#34;&gt;Dragon Swing 2016&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://yewtu.be/watch?v=0DHUfThIrlA&#34;&gt;Warsaw Shag Festival 2018&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://yewtu.be/watch?v=6wasM8nF9gg&#34;&gt;Warsaw Shag Festival 2017&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;lindy-hop&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/lindy/&#34;&gt;Lindy Hop&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: New Charleston, lindy and solo jazz videos.&lt;/p&gt; &lt;p&gt;Charleston:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The DecaVita Sisters:&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=OV6ZDuczkag&#34;&gt;Freestyle Lindy Hop &amp;amp; Charleston&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=ciMFQnwfp50&#34;&gt;Moby &#34;Honey&#34;&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Solo Jazz:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://yewtu.be/watch?v=pmxn2uIVuUY&#34;&gt;Pedro Vieira at Little Big Swing Camp 2022&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Lindy Hop:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The DecaVita Sisters:&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/3DhD2u5Eyv8?si=2WKisSvEB3Z8TVMy&#34;&gt;Compromise - agreement in the moment&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=qkdxcdeicLE&#34;&gt;Lindy hop improv&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/lindy/#charleston&#34;&gt;Add Hellzapopping videos.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=ahoJReiCaPk&#34;&gt;Short version&lt;/a&gt; &lt;a href=&#34;https://www.youtube.com/watch?v=aQia-42W-v8&#34;&gt;Long version&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;maker&#34;&gt;Maker&lt;/h3&gt; &lt;h4 id=&#34;vial&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vial/&#34;&gt;Vial&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Vial.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://get.vial.today/&#34;&gt;Vial&lt;/a&gt; is an open-source cross-platform (Windows, Linux and Mac) GUI and a QMK fork for configuring your keyboard in real time.&lt;/p&gt; &lt;p&gt;Even though you can use a &lt;a href=&#34;https://vial.rocks/&#34;&gt;web version&lt;/a&gt; you can install it locally through an &lt;a href=&#34;https://itsfoss.com/use-appimage-linux/&#34;&gt;AppImage&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Download &lt;a href=&#34;https://get.vial.today/download/&#34;&gt;the latest version&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Give it execution permissions&lt;/li&gt; &lt;li&gt;Add the file somewhere in your &lt;code&gt;$PATH&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;On linux you &lt;a href=&#34;https://get.vial.today/manual/linux-udev.html&#34;&gt;need to configure an &lt;code&gt;udev&lt;/code&gt; rule&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;For a universal access rule for any device with Vial firmware, run this in your shell while logged in as your user (this will only work with sudo installed):&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;USER_GID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;id&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-g&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--preserve-env&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;USER_GID&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sh&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;echo &#34;KERNEL==\&#34;hidraw*\&#34;, SUBSYSTEM==\&#34;hidraw\&#34;, ATTRS{serial}==\&#34;*vial:f64c2b3c*\&#34;, MODE=\&#34;0660\&#34;, GROUP=\&#34;$USER_GID\&#34;, TAG+=\&#34;uaccess\&#34;, TAG+=\&#34;udev-acl\&#34;&#34; &amp;gt; /etc/udev/rules.d/99-vial.rules &amp;amp;&amp;amp; udevadm control --reload &amp;amp;&amp;amp; udevadm trigger&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This command will automatically create a &lt;code&gt;udev&lt;/code&gt; rule and reload the &lt;code&gt;udev&lt;/code&gt; system.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;video-gaming&#34;&gt;Video Gaming&lt;/h3&gt; &lt;h4 id=&#34;age-of-empires&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/age_of_empires/&#34;&gt;Age of Empires&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add guides on how to play.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=JsTNM7j6fs4&amp;amp;t=119&#34;&gt;Fast castle boom&lt;/a&gt;&lt;/li&gt; &lt;li&gt;How to play Arena: &lt;a href=&#34;https://piped.video/watch?v=8gXI4XGMPzQ&amp;amp;t=0&#34;&gt;Hera&#39;s guide&lt;/a&gt;, &lt;a href=&#34;https://www.youtube.com/watch?v=3qg4Xwm8CAo&amp;amp;t=1211&#34;&gt;Tatoh game in arena&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=DdK8QveBegw&amp;amp;t=652&#34;&gt;How to play Hideout&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=1V_jsU9PF8Y&#34;&gt;How to play Blackforest&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Inside the mind of a pro player: &lt;a href=&#34;https://www.youtube.com/watch?v=54hRmrdzO-I&#34;&gt;Episode 1&lt;/a&gt;, &lt;a href=&#34;https://www.youtube.com/watch?v=sZCs6dwH5qk&amp;amp;t=1727&#34;&gt;Episode 2&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/age_of_empires/#-strategies-against-civilisations&#34;&gt;Strategies against civilisations.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I&#39;m using only the mongols, and so far I&#39;ve seen/heard from the pros the next strategies:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Aztecs:&lt;ul&gt; &lt;li&gt;Steppe lancers good against eagle warriors&lt;/li&gt; &lt;li&gt;Heavy scorpions against eagle warriors and skirms&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Cumans:&lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=H9QUNtFII1g&amp;amp;t=0&#34;&gt;Scout, if it drops two TCs in feudal, tower rush into archers&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=R9qaFZzZgBY&amp;amp;t=1925&#34;&gt;Put initial pressure&lt;/a&gt;: Nice initial pressure&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Incas:&lt;ul&gt; &lt;li&gt;Steppe lancers good against eagle warriors&lt;/li&gt; &lt;li&gt;Heavy scorpions against eagle warriors and skirms&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Khmer: boom, map control, monks and albadiers&lt;/li&gt; &lt;li&gt;Mayans:&lt;ul&gt; &lt;li&gt;Steppe lancers good against eagle warriors&lt;/li&gt; &lt;li&gt;Heavy scorpions against eagle warriors and skirms&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Romans:&lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=SA44-Y3XUy0&amp;amp;t=842&#34;&gt;Hera guide on how to beat them&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Tartars: heavy scorpions&lt;/li&gt; &lt;li&gt;Turks:&lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=AI_JRA_nCpw&amp;amp;t=3710&#34;&gt;How to defend against them in Arena&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/age_of_empires/#nice-games&#34;&gt;Nice games.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Tournaments:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;2023 Masters of Arena 7 Final Tatoh vs Vinchester:&lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=3qg4Xwm8CAo&amp;amp;t=1211s&#34;&gt;Casted by T90&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=AI_JRA_nCpw&amp;amp;t=8854&#34;&gt;Pov by Tatoh&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Showmatches:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=AlKMRQNMVzo&amp;amp;t=4306&#34;&gt;Hera vs TheViper | Battlegrounds 3 | BO5&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=5_p3TXasBHY&amp;amp;t=5319&#34;&gt;The Viper VS Tatoh PA7&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;1vs1 games:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=iZ7eWLLbh34&#34;&gt;Hindustanis vs Portuguese | Arabia | Hera vs Yo&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=tZyVLDwBfd4&#34;&gt;Dravidians vs Turks | African Clearing | Hera vs Yo&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: How to fight Vietnamese with Mongols.&lt;/p&gt; &lt;p&gt;Gain early map control with scouts, then switch into steppe lancers and front siege, finally castle in the face when you clicked to imperial.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://yewtu.be/watch?v=20bktCBldcw&#34;&gt;Example Hera vs Mr.Yo in TCI&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/age_of_empires/#references&#34;&gt;Added references.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/@HeraAgeofEmpires2&#34;&gt;Hera channel&lt;/a&gt;: Awesome to learn to play&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/@Hera-Gameplay&#34;&gt;Hera gameplay channel&lt;/a&gt;: Good 1&lt;sup&gt;st&lt;/sup&gt; person point of view games&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/@TaToHAoE&#34;&gt;Tatoh channel&lt;/a&gt;: Good spanish content.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;gardening&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gardening/&#34;&gt;Gardening&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gardening/#fertilizing-with-manure&#34;&gt;Fertilizing with manure.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Manure is one of the best organic fertilizers for plants. It&#39;s made by the accumulation of excrements of bats, sea birds and seals and it usually doesn&#39;t contain additives or synthetic chemical components.&lt;/p&gt; &lt;p&gt;This fertilizer is rich in nitrogen, phosphorus and potassium, which are key minerals for the growth of plants. These components help the regeneration of the soil, the enrichment in terms of nutrients and also acts as fungicide preventing plagues.&lt;/p&gt; &lt;p&gt;Manure is a fertilizer of slow absorption, which means that it&#39;s released to the plants in an efficient, controlled and slow pace. That way the plants take the nutrients when they need them.&lt;/p&gt; &lt;p&gt;The best moment to use it is at spring and depending on the type of plant you should apply it between each month and a half and three months. It&#39;s use in winter is not recommended, as it may burn the plant&#39;s roots.&lt;/p&gt; &lt;p&gt;Manure can be obtained in dust or liquid state. The first is perfect to scatter directly over the earth, while the second is better used on plant pots. You don&#39;t need to use much, in fact, with just a pair of spoons per pot is enough. Apply it around the base of the plant, avoiding it&#39;s touch with leaves, stem or exposed roots, as it may burn them. After you apply them remember to water them often, keep in mind that it&#39;s like a heavy greasy sandwich for the plants, and they need water to digest it.&lt;/p&gt; &lt;p&gt;For my indoor plants I&#39;m going to apply a small dose (one spoon per plant) at the start of Autumn (first days of September), and two spoons at the start of spring (first days of March).&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;emojis&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/emojis/&#34;&gt;Emojis&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/emojis/#most-used&#34;&gt;Create a list of most used emojis.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;¯\(°_o)/¯

¯\_(ツ)_/¯

(╯°□°)╯ ┻━┻

＼\ ٩( ᐛ )و /／

(✿◠‿◠)

(/ﾟДﾟ)/

(¬º-°)¬

(╥﹏╥)

ᕕ( ᐛ )ᕗ

ʕ•ᴥ•ʔ

( ˘ ³˘)♥

❤
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add new emojis.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;(╥_╥)
(*≧▽≦)ﾉｼ))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;science&#34;&gt;Science&lt;/h2&gt; &lt;h3 id=&#34;math&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/math/&#34;&gt;Math&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/math/#videos&#34;&gt;Add 3Blue1Brown videos.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.youtube.com/channel/UCYO_jab_esuFRV4b17AJtAw&#34;&gt;3Blue1Brown&lt;/a&gt;. Recomended by &lt;a href=&#34;https://ncase.me/&#34;&gt;Nicky Case&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;other&#34;&gt;Other&lt;/h2&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Update introduction.&lt;/p&gt; &lt;p&gt;The method was described by David Allen in a book with the same name. It&#39;s clear that the book is the corner stone of David&#39;s business. He is selling his method on every word, some times to the point of tiresome. It&#39;s also repeats the same ideas on different parts of the book, I guess that&#39;s good in terms of sticking an idea in the people&#39;s mind, but if you&#39;re already convinced and are trying to sum up the book it&#39;s like, hey, I have 90% of the valuable contents of this chapter already in my summary. It&#39;s obvious too the context of the writer, that the book was written a while ago and who does it write to. It talks quite often about assistants, bosses of high firm companies he&#39;s helped, preferring low-tech physical solutions over digital ones, a lot of references about parenting... If you&#39;re able to ignore all the above, it&#39;s actually a very good book. The guy has been polishing the method for more than 30 years, and has pretty nice ideas that can change how you manage your life.&lt;/p&gt; &lt;p&gt;My idea of this summary is to try to extract the useful ideas removing all those old-fashioned capitalist values from it.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Guides on processing your inbox.&lt;/p&gt; &lt;p&gt;Remember to follow the next rules while processing the items:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Process the top item first: that way you treat each element equally, so the &#34;least&#34; important ones are not left dangling forever in your inbox thus thwarting it&#39;s purpose.&lt;/li&gt; &lt;li&gt;Process one item at a time.&lt;/li&gt; &lt;li&gt;Never put anything back into “in.”&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;For each element you need to ask yourself: &#34;What&#39;s the next action?&#34;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: How to clarify your inbox items.&lt;/p&gt; &lt;p&gt;If you can do something about the element, you need to think which is the next physical, visible activity that would be required to move the situation towards closure. It&#39;s tricky, something like &#34;set meeting&#34; won&#39;t do because it&#39;s not descriptive of physical behaviour. There is still stuff to decide how, when, with whom, if you don&#39;t do it now you won&#39;t empty your head and the uncertainty will create a psychological gap that will make you procrastinate, so define the next action now. &#34;Decide what to do about X&#34; doesn&#39;t work either, you may need to gather more information on the topic, but deciding doesn&#39;t take time.&lt;/p&gt; &lt;p&gt;Once you have the next action, if it can be done in two minutes or less, do it when you first pick the item up. Even if it is not a high-priority one, do it now if you’re ever going to do it at all. The rationale for the two-minute rule is that it’s more or less the point where it starts taking longer to store and track an item than to deal with it the first time it’s in your hands. Two minutes is just a guideline. If you have a long open window of time in which to process your in-tray, you can extend the cutoff for each item to five or ten minutes. If you’ve got to get to the bottom of all your input rapidly, then you may want to shorten the time to one minute, or even thirty seconds, so you can get through everything a little faster.&lt;/p&gt; &lt;p&gt;There’s nothing you really need to track about your two-minute actions. Just do them. If, however, you take an action and don’t finish the project with that one action, you’ll need to clarify what’s next on it, and manage that according to the same criteria.&lt;/p&gt; &lt;p&gt;If the next action is going to take longer than two minutes, ask yourself, “Am I the best person to be doing it?” If not, hand it off to the appropriate person, in order of priority:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Send an e-mail.&lt;/li&gt; &lt;li&gt;Write a note or an over-note on paper and route it to that person.&lt;/li&gt; &lt;li&gt;Send it a instant message.&lt;/li&gt; &lt;li&gt;Add it as an agenda item on a list for your next real-time conversation with that person.&lt;/li&gt; &lt;li&gt;Talk with her directly, either face-to-face or by phone.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;When you hand it off to someone else, and if you care at all whether something happens as a result, you’ll need to track it. Depending on how active you need to be it can go to your Waiting list or to your tickler.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Deprecate pydo.&lt;/p&gt; &lt;p&gt;I&#39;m happy with orgmode so far, so I&#39;m not going to continue it&#39;s development&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: UPGRADE FAILED: another operation (install/upgrade/rollback) is in progress.&lt;/p&gt; &lt;p&gt;This error can happen for few reasons, but it most commonly occurs when there is an interruption during the upgrade/install process as you already mentioned.&lt;/p&gt; &lt;p&gt;To fix this one may need to, first rollback to another version, then reinstall or helm upgrade again.&lt;/p&gt; &lt;p&gt;Try below command to list the available charts:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;helm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ls&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--namespace&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;namespace&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You may note that when running that command ,it may not show any columns with information. If that&#39;s the case try to check the history of the previous deployment&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;helm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;history&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;release&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--namespace&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;namespace&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This provides with information mostly like the original installation was never completed successfully and is pending state something like STATUS: &lt;code&gt;pending-upgrade&lt;/code&gt; state.&lt;/p&gt; &lt;p&gt;To escape from this state, use the rollback command:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;helm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rollback&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;release&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;revision&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--namespace&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;namespace&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;code&gt;revision&lt;/code&gt; is optional, but you should try to provide it.&lt;/p&gt; &lt;p&gt;You may then try to issue your original command again to upgrade or reinstall.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Ansible retry a failed job.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/usr/bin/false&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;retries&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;3&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;delay&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;3&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;register&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;result&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;until&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;result.rc == 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce Bookwyrm.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://joinbookwyrm.com/&#34;&gt;Bookwyrm&lt;/a&gt; is a social network for tracking your reading, talking about books, writing reviews, and discovering what to read next. Federation allows BookWyrm users to join small, trusted communities that can connect with one another, and with other ActivityPub services like Mastodon and Pleroma.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce Elastic security.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.elastic.co/security&#34;&gt;Elastic security&lt;/a&gt; is a program to protect, investigate, and respond to complex threats by unifying the capabilities of SIEM, endpoint security, and cloud security.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce RSS.&lt;/p&gt; &lt;p&gt;Note: This post is a shameless direct copy of &lt;a href=&#34;https://ncase.me/rss/&#34;&gt;Nicky beautiful post, read it there as it has beautiful illustrations&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://ncase.me/rss/&#34;&gt;What is RSS (Really Simple Syndication)?&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Imagine an open version of Twitter or Facebook News Feed, with no psy-op ads, owned by no oligopoly, manipulated by no algorithm, and all under your full control.&lt;/p&gt; &lt;p&gt;Imagine a version of the newsletter where you don&#39;t have to worry about them selling your email to scammers, labyrinth-like unsubscribe pages, or stuffing your inbox with ever more crap.&lt;/p&gt; &lt;p&gt;Now imagine this existed and was extremely popular 15 years ago. Then we got suckered by the shiny walled gardens.&lt;/p&gt; &lt;p&gt;Well, it&#39;s time to make like a tree and go back to the future, baby!&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://ncase.me/rss/&#34;&gt;How does RSS work?&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Unlike newsletters where give each publisher your email (and they may abuse that trust), RSS works on a &#34;don&#39;t call me, I&#39;ll call you&#34; policy.&lt;/p&gt; &lt;p&gt;An RSS feed is a text file on a website. It&#39;s just a bunch of posts – no tracking or &#34;personalization&#34; – like a printed newspaper:&lt;/p&gt; &lt;p&gt;Then, whatever RSS reader app you use – you can use any app made by anyone – it&#39;ll call the websites for the feeds you specifically opted into, no more or less. The websites can&#39;t force it in the other direction.&lt;/p&gt; &lt;p&gt;Your app then shows you your posts in good ol&#39; reverse chronological order. (Some apps let you add extra filters, but unlike social media algorithms, you control &#39;em.) Apps also make the posts prettier than raw text:&lt;/p&gt; &lt;p&gt;Really Simple, indeed!&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://ncase.me/rss/&#34;&gt;Cool, how do I get started?&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;First, you need a reader app. Such as the minimalist &lt;a href=&#34;https://www.inoreader.com/&#34;&gt;Inoreader&lt;/a&gt;, but &lt;a href=&#34;https://feedly.com/&#34;&gt;Feedly&lt;/a&gt; is the most popular, and folks use &lt;a href=&#34;https://theoldreader.com/&#34;&gt;The Old Reader&lt;/a&gt;. See this &lt;a href=&#34;https://zapier.com/blog/best-rss-feed-reader-apps/&#34;&gt;list of readers&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;To add a feed to your app, just paste a link to the blog/site, and your app will automatically find the feed! RSS also lets you follow creators on YouTube, Substack, Medium, and more.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://ncase.me/rss/&#34;&gt;Tips for using RSS wisely&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Beware the hoarder instinct. No algorithm can save you from hoarding feeds &#34;just in case&#34;, then being overwhelmed. The only cure is to ruthlessly Marie Kondo that crap – if a feed doesn&#39;t consistently enrich your life, cut it.&lt;/li&gt; &lt;li&gt;Some feeds only give you the excerpt of a post, with a link to see the full post at their site. Don&#39;t follow those: they break you out of the RSS reading experience, and trick you into losing time on their site. (This is a harsh rule: I used to follow Quanta Magazine&#39;s feed, but they switched from full-text to excerpts, so I unsubscribed.)&lt;/li&gt; &lt;li&gt;Don&#39;t follow feeds that update more than once a day. Go for daily digests, or better yet, weekly digests.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://ncase.me/rss/&#34;&gt;If RSS Was So Great, Why&#39;d It Die In The First Place&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Well, Google killed Google Reader in 2013, the #1 RSS reader at the time. This was to make way for Google Plus, which failed. The sacrificial lamb was for nothing.&lt;/p&gt; &lt;p&gt;But Google only did what nearly everyone – including yours truly – did in 2013: leave the open, decentralized Web 1.0 for the shiny new Web 2.0 platforms. Why? Well, it was more fun &amp;amp; convenient.&lt;/p&gt; &lt;p&gt;But now in 2021, for most of us, social media is very not fun and not convenient. That&#39;s why I went back to the future with RSS, and wrote this post encouraging you to do the same!&lt;/p&gt; &lt;p&gt;(Ok, RSS had two more problems: 1) Getting overwhelmed with feeds. As said above, the only cure is to trim ruthlessly. 2) RSS lets you serve text/link/image ads, but not the creepy user-tracking ads. In 2013 that was the &#34;best&#34; way make money on the web, but these days ad revenue is dying, and subscriptions like Patreon/Substack are thriving.)&lt;/p&gt; &lt;p&gt;And that&#39;s all, folks! Now you know how to escape the attention-draining, empathy-killing, critical-thought-suffocating siren song of the algorithms. And get your inbox less cluttered with newsletters.&lt;/p&gt; &lt;p&gt;Here&#39;s to a renaissance for a kinder, better web. &amp;lt;3&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce the analysis of life process.&lt;/p&gt; &lt;p&gt;It&#39;s interesting to do analysis at representative moments of the year. It gives it an emotional weight. You can for example use the solstices or my personal version of the solstices:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Spring analysis (1&lt;sup&gt;st&lt;/sup&gt; of March): For me the spring is the real start of the year, it&#39;s when life explodes after the stillness of the winter. The sun starts to set later enough so that you have light in the afternoons, the climate gets warmer thus inviting you to be more outside, the nature is blooming new leaves and flowers. It is then a moment to build new projects and set the current year on track.&lt;/li&gt; &lt;li&gt;Summer analysis (1&lt;sup&gt;st&lt;/sup&gt; of June): I hate heat, so summer is a moment of retreat. Everyone temporarily stop their lives, we go on holidays and all social projects slow their pace. Even the news have even less interesting things to report. It&#39;s so hot outside that some of us seek the cold refuge of home or remote holiday places. Days are long and people love to hang out till late, so usually you wake up later, thus having less time to actually do stuff. Even in the moments when you are alone the heat drains your energy to be productive. It is then a moment to relax and gather forces for the next trimester. It&#39;s also perfect to develop &lt;em&gt;easy&lt;/em&gt; and &lt;em&gt;chill&lt;/em&gt; personal projects that have been forgotten in a drawer. Lower your expectations and just flow with what your body asks you.&lt;/li&gt; &lt;li&gt;Autumn analysis (1&lt;sup&gt;st&lt;/sup&gt; of September): September it&#39;s another key moment for many people. We have it hardcoded in our life since we were children as it was the start of school. People feel energized after the summer holidays and are eager to get back to their lives and stopped projects. You&#39;re already 6 months into the year, so it&#39;s a good moment to review your year plan and decide how you want to invest your energy reserves.&lt;/li&gt; &lt;li&gt;Winter analysis (1&lt;sup&gt;st&lt;/sup&gt; of December): December is the cue that the year is coming to an end. The days grow shorter and colder, they basically invite you to enjoy a cup of tea under a blanket. It is then a good time to get into your cave and do an introspection analysis on the whole year and prepare the ground for the coming year.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;We see then that the year is divided in two sets of an expansion trimester and a retreat one. We can use this information to plan our tasks accordingly. In the expansion trimester we could invest more energies in the planning, and in the retreat ones we can do more throughout reviews.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: How to create a prometheus exporter with python.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/prometheus/client_python&#34;&gt;prometheus-client&lt;/a&gt; is the official Python client for &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/prometheus/&#34;&gt;Prometheus&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Installation:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;prometheus-client
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Here is a simple script:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;prometheus_client&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;start_http_server&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Summary&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;random&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;time&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;REQUEST_TIME&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;request_processing_seconds&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;Time spent processing request&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;nd&#34;&gt;@REQUEST_TIME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;process_request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;A dummy function that takes some time.&#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sleep&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;__main__&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;# Start up the server to expose the metrics.&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;start_http_server&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;8000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;# Generate some requests.&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;process_request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;random&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;random&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then you can visit &lt;a href=&#34;http://localhost:8000/&#34;&gt;http://localhost:8000/&lt;/a&gt; to view the metrics.&lt;/p&gt; &lt;p&gt;From one easy to use decorator you get:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;request_processing_seconds_count&lt;/code&gt;: Number of times this function was called.&lt;/li&gt; &lt;li&gt;&lt;code&gt;request_processing_seconds_sum&lt;/code&gt;: Total amount of time spent in this function.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Prometheus&#39;s rate function allows calculation of both requests per second, and latency over time from this data.&lt;/p&gt; &lt;p&gt;In addition if you&#39;re on Linux the process metrics expose CPU, memory and other information about the process for free.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;aside class=&#34;md-source-file&#34;&gt; &lt;span class=&#34;md-source-file__fact&#34;&gt; &lt;span class=&#34;md-icon&#34; title=&#34;Last update&#34;&gt; &lt;svg viewbox=&#34;0 0 24 24&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z&#34;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt; &lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago&#34; title=&#34;November 27, 2024 15:36:58 UTC&#34;&gt;&lt;span class=&#34;timeago&#34; datetime=&#34;2024-11-27T15:36:58+00:00&#34; locale=&#34;en&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date&#34; title=&#34;November 27, 2024 15:36:58 UTC&#34;&gt;2024-11-27&lt;/span&gt; &lt;/span&gt; &lt;/aside&gt; &lt;/article&gt;</description>
      <link>https://lyz-code.github.io/blue-book/newsletter/2023/</link>
      <pubDate>2024-11-27 15:36:58+00:00</pubDate>
      <source url="https://lyz-code.github.io/blue-book/yearly.xml">The Blue Book</source>
      <guid isPermaLink="true">https://lyz-code.github.io/blue-book/newsletter/2023/</guid>
      
    </item>
    
    <item><title>2022</title>
      <author>Lyz</author>
      <description>&lt;article class=&#34;md-content__inner md-typeset&#34;&gt;  &lt;h2 id=&#34;introduction&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/&#34;&gt;Introduction&lt;/a&gt;&lt;/h2&gt; &lt;ul&gt; &lt;li&gt;New: Add the donation information.&lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;projects&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/&#34;&gt;Projects&lt;/a&gt;&lt;/h2&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add two more solutions to the voice recognition project.&lt;/p&gt; &lt;p&gt;For offline voice recognition, &lt;a href=&#34;https://github.com/alphacep/vosk-api&#34;&gt;vosk-api&lt;/a&gt; can be used. Or &lt;a href=&#34;https://github.com/maxkrieger/voiceliner/issues/37&#34;&gt;voiceliner&lt;/a&gt; once it supports offline voice recognition.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#faker-optional&#34;&gt;Deprecate faker-optional project.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Wrapper over other Faker providers to return their value or &lt;code&gt;None&lt;/code&gt;. Useful to create data of type &lt;code&gt;Optional[Any]&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Not needed anymore as I use &lt;a href=&#34;https://lyz-code.github.io/blue-book/pydantic_factories/&#34;&gt;pydantic factories&lt;/a&gt; now.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#life-warnings&#34;&gt;Create the Life Warnings seed.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I&#39;ve always tackled the pursuit of the peace of mind by improving in task management, for example trying to predict when I have to do something in order to avoid a nuisance. Maybe it&#39;s more interesting to monitor and visibilice the warnings that are affecting you.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Reorganization: Merge Self host a routing web application seed with host my own map seedling.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#create-an-ordered-list-of-digital-gardens&#34;&gt;Create an ordered list of digital gardens.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Created &lt;a href=&#34;https://github.com/lyz-code/best-of-digital-gardens&#34;&gt;Best-of Digital Gardens&lt;/a&gt; a &lt;a href=&#34;https://github.com/best-of-lists/best-of&#34;&gt;best-of-lists&lt;/a&gt; compilation of awesome list of digital gardens.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#beancount-forecast&#34;&gt;Beancount forecast.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I&#39;d like to see a forecast of the evolution of my accounts given an amount of time. Maybe by doing seasonality analysis and forecast in time series as stated &lt;a href=&#34;https://medium.com/swlh/seasonality-analysis-and-forecast-in-time-series-b8fbba820327&#34;&gt;here&lt;/a&gt; and &lt;a href=&#34;https://towardsdatascience.com/finding-seasonal-trends-in-time-series-data-with-python-ce10c37aa861&#34;&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;It will also be interesting to see for a given account the evolution of the subaccounts.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#version-update-manager&#34;&gt;Version Update Manager.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Keeping software updated is not easy because:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;There are many technologies involved: package managers (apt, yum, pip, yarn, npm, ...), programming languages (python, java, ruby, ...), operative systems (Debian, Ubuntu, ...), deployment technologies (OS install, Docker, Kubernetes, Ansible, Helm), template software (cruft).&lt;/li&gt; &lt;li&gt;Each software maintainers use a different version system.&lt;/li&gt; &lt;li&gt;Even a small increase in a version may break everything.&lt;/li&gt; &lt;li&gt;Sometimes only the latest version is the supported version.&lt;/li&gt; &lt;li&gt;It&#39;s not easy to check if the update went well.&lt;/li&gt; &lt;li&gt;You not only need the desired package to be updated, but also it&#39;s dependencies.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;I&#39;d like to find a solution that:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Gives an overall insight of the update status of a system.&lt;/li&gt; &lt;li&gt;Automates the update process.&lt;/li&gt; &lt;li&gt;Support both single system installation or aggregator of multiple systems.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;activism&#34;&gt;Activism&lt;/h2&gt; &lt;h3 id=&#34;antifascism&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/antifascism/&#34;&gt;Antifascism&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/antifascism/#magazines&#34;&gt;Add magazines and podcasts.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Magazines:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://hopenothate.org.uk&#34;&gt;Hope not Hate&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.searchlightmagazine.com/&#34;&gt;Searchlight&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Podcasts:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://hopenothate.org.uk/research/podcast/&#34;&gt;Hope not Hate&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/antifascism/#how-to-fight-fascism&#34;&gt;How to fight fascism.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;There are many ways to fight it, the book &lt;a href=&#34;https://www.txalaparta.eus/es/libros/todo-el-mundo-puede-ser-antifa&#34;&gt;Todo el mundo puede ser Antifa: Manual practico para destruir el fascismo of Pol Andiñach&lt;/a&gt; gathers some of them.&lt;/p&gt; &lt;p&gt;One way we&#39;ve seen pisses them off quite much is when they are ridiculed and they evocate the image of incompetence. It&#39;s a fine line to go, because if it falls into a pity image then it may strengthen their victim role.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;antifascist-actions&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/antifascist_actions/&#34;&gt;Antifascist Actions&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/antifascist_actions/#an-open-data-initiative-to-map-spanish-fascist-icons&#34;&gt;An open data initiative to map spanish fascist icons.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The project &lt;a href=&#34;https://deberiadesaparecer.com&#34;&gt;DeberíaDesaparecer&lt;/a&gt; have created an open database of the remains of the spanish fascist regime icons. The visualization they&#39;ve created is astonishing, and they&#39;ve provided a &lt;a href=&#34;https://docs.google.com/forms/d/e/1FAIpQLSc8jY6y0vcjQKNJBougQG_gTOUSfZGBhponOiwij9xVIwIafA/viewform?embedded=true&#34;&gt;form&lt;/a&gt; so that anyone can contribute to the dataset.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/antifascist_actions/#an-open-data-initiative-to-map-spanish-hate-crimes&#34;&gt;An open data initiative to map spanish hate crimes.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The project &lt;a href=&#34;https://crimenesdeodio.info/es/&#34;&gt;Crimenes de Odio&lt;/a&gt; have created an open database of the hate crimes registered in the spanish state.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;feminism&#34;&gt;Feminism&lt;/h3&gt; &lt;h4 id=&#34;privileges&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/feminism/privileges/&#34;&gt;Privileges&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: How to reduce online racism.&lt;/p&gt; &lt;p&gt;Add article &lt;a href=&#34;https://www.websiteplanet.com/blog/how-to-reduce-online-racism&#34;&gt;How to reduce online racism by Mark Holden&lt;/a&gt;, a long essay with interesting tips and a lot of useful visualizations, I haven&#39;t checked the sources but it looks legit. (Thanks for the recommendation Laurie &lt;code&gt;:)&lt;/code&gt;).&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;mentoring&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/mentoring/&#34;&gt;Mentoring&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the concept and guidelines of mentorship.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Mentorship&#34;&gt;Mentoring&lt;/a&gt; is a process for the informal transmission of knowledge, social capital, and the psychosocial support perceived by the recipient as relevant to work, career, or professional development; mentoring entails informal communication, usually face-to-face and during a sustained period of time, between a person who is perceived to have greater relevant knowledge, wisdom, or experience (the mentor) and a person who is perceived to have less (the apprentice).&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;environmentalism&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/environmentalism/&#34;&gt;Environmentalism&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce carbon fingerprint calculation tools.&lt;/p&gt; &lt;p&gt;Measure the carbon footprint of your travels&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.carbonfootprint.com/&#34;&gt;https://www.carbonfootprint.com/&lt;/a&gt;&lt;/p&gt; &lt;p&gt;There are also some calculators for events itself:&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://co2.myclimate.org/en/event_calculators/new&#34;&gt;https://co2.myclimate.org/en/event_calculators/new&lt;/a&gt; &lt;a href=&#34;https://psci.princeton.edu/events-emissions-calculator&#34;&gt;https://psci.princeton.edu/events-emissions-calculator&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/environmentalism/#saving-water&#34;&gt;Saving water.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Here are some small things I&#39;m doing to save some water each day:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Use the watering can or a bucket to gather the shower water until it&#39;s warm enough. I use this water to flush the toilet. It would be best if it were possible to fill up the toilet&#39;s deposit, but it&#39;s not easy.&lt;/li&gt; &lt;li&gt;Use a glass of water to wet the toothbrush and rinse my mouth instead of using running water.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;life-management&#34;&gt;Life Management&lt;/h2&gt; &lt;h3 id=&#34;task-management&#34;&gt;Task Management&lt;/h3&gt; &lt;h4 id=&#34;openproject&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/roadmap_tools/&#34;&gt;OpenProject&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce OpenProject.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.openproject.org/&#34;&gt;OpenProject&lt;/a&gt; is an Open source project management software.&lt;/p&gt; &lt;p&gt;The benefits over other &lt;a href=&#34;https://lyz-code.github.io/blue-book/roadmap_tools/#web-based-task-manager&#34;&gt;similar software are&lt;/a&gt;:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;It&#39;s popular: More than 6.2k stars on github, 1.7k forks.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/opf/openproject/pulse&#34;&gt;It&#39;s development is active&lt;/a&gt;: in the last week they&#39;ve merged 44 merged pull requests by 16 people.&lt;/li&gt; &lt;li&gt;They use their own software to &lt;a href=&#34;https://community.openproject.org/projects/openproject/&#34;&gt;track their bugs&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/opf/openproject-deploy&#34;&gt;Easy to install&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Easy to use&lt;/li&gt; &lt;li&gt;The community version is flexible enough to adapt to different workflows.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.openproject.org/docs/installation-and-operations/&#34;&gt;Good installation and operation&#39;s documentation&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;Very good API documentation.&lt;/li&gt; &lt;li&gt;Supports LDAP&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The things I don&#39;t like are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Data can be exported as XML or CSV but it doesn&#39;t export everything. You have access to the database though, so if you&#39;d like a better extraction of the data you in theory can do a selective dump of whatever you need.&lt;/li&gt; &lt;li&gt;It doesn&#39;t yet have &lt;a href=&#34;https://community.openproject.org/projects/openproject/work_packages/32181/activity&#34;&gt;tag support&lt;/a&gt;. You can meanwhile add the strings you would use as tags in the description, and then filter by text in description.&lt;/li&gt; &lt;li&gt;There is no demo instance where you can try it. It&#39;s easy though to launch a &lt;a href=&#34;#proof-of-concept&#34;&gt;Proof of Concept environment yourself&lt;/a&gt; if you already know &lt;code&gt;docker-compose&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;Even thought the &lt;a href=&#34;https://www.openproject.org/pricing/#features&#34;&gt;Community (free) version has many features&lt;/a&gt; the next aren&#39;t:&lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.openproject.org/docs/user-guide/agile-boards/#status-board&#34;&gt;Status boards&lt;/a&gt;: you can&#39;t have Kanban boards that show the state of the issues as columns. You can make it yourself through a Basic board and with the columns as the name of the state. But when you transition an issue from state, you need to move the issue and change the property yourself. I&#39;ve thought of creating a script that works with the API to do this automatically, maybe through the webhooks of the openproject, but it would make more sense to spend time on &lt;code&gt;pydo&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.openproject.org/docs/user-guide/agile-boards/#version-board&#34;&gt;Version boards&lt;/a&gt;: Useful to transition issues between sprints when you didn&#39;t finish them in time. Probably this is easily solved through bulk editing the issues.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.openproject.org/docs/system-admin-guide/manage-work-packages/custom-actions/&#34;&gt;Custom actions&lt;/a&gt; looks super cool, but as this gives additional value compared with the competitors, I understand it&#39;s a paid feature.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.openproject.org/docs/user-guide/work-packages/work-package-relations-hierarchies/#display-relations-in-work-package-list-premium-feature&#34;&gt;Display relations in the work package list&lt;/a&gt;: It would be useful to quickly see which tasks are blocked, by whom and why. Nothing critical though.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.openproject.org/docs/system-admin-guide/custom-fields/#create-a-multi-select-custom-field-premium-feature&#34;&gt;Multiselect custom fields&lt;/a&gt;: You can only do single valued fields. Can&#39;t understand why this is a paid feature.&lt;/li&gt; &lt;li&gt;2FA authentication is only an Enterprise feature.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.openproject.org/docs/system-admin-guide/authentication/openid-providers/&#34;&gt;OpenID and SAML&lt;/a&gt; are an enterprise feature.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Also included:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/openproject/#installation&#34;&gt;How to install it&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/openproject/#operation&#34;&gt;How to operate it&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/openproject/#tips&#34;&gt;Tips&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/roadmap_tools/#web-based-task-manager&#34;&gt;Web based task manager.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Life happened and the development of &lt;a href=&#34;https://lyz-code.github.io/pydo&#34;&gt;pydo&lt;/a&gt; has fallen behind in my priority list. I&#39;ve also reached a point where &lt;a href=&#34;#the-simplest-task-manager&#34;&gt;simplest one&lt;/a&gt; is no longer suitable for my workflow because:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;I loose a lot of time in the reviews.&lt;/li&gt; &lt;li&gt;I loose a lot of time when doing the different plannings (year, trimester, month, week, day).&lt;/li&gt; &lt;li&gt;I find it hard to organize and refine the backlog.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;As &lt;code&gt;pydo&lt;/code&gt; is not ready yet and I need a solution that works &lt;em&gt;today&lt;/em&gt; better than the simplest task manager, I&#39;ve done an analysis of the state of the art of &lt;a href=&#34;https://github.com/awesome-selfhosted/awesome-selfhosted#software-development---project-management&#34;&gt;self-hosted applications&lt;/a&gt; of all of them the two that were more promising were &lt;a href=&#34;https://lyz-code.github.io/blue-book/roadmap_tools/#taiga&#34;&gt;Taiga&lt;/a&gt; and &lt;a href=&#34;https://lyz-code.github.io/blue-book/roadmap_tools/#openproject&#34;&gt;OpenProject&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Finally I chose &lt;a href=&#34;https://lyz-code.github.io/blue-book/openproject/&#34;&gt;OpenProject&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/openproject/#deal-with-big-number-of-tasks&#34;&gt;Deal with big number of tasks.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;As the number of tasks increase, the views of your work packages starts becoming more cluttered. As you &lt;a href=&#34;https://community.openproject.org/projects/openproject/work_packages/31918/activity&#34;&gt;can&#39;t fold the hierarchy trees&lt;/a&gt; it&#39;s difficult to efficiently manage your backlog.&lt;/p&gt; &lt;p&gt;I&#39;ve tried setting up a work package type that is only used for the subtasks so that they are filtered out of the view, but then you don&#39;t know if they are parent tasks unless you use the details window. It&#39;s inconvenient but having to collapse the tasks every time it&#39;s more cumbersome. You&#39;ll also need to reserve the selected subtask type (in my case &lt;code&gt;Task&lt;/code&gt;) for the subtasks.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/openproject/#sorting-work-package-views&#34;&gt;Sorting work package views.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;They are sorted alphabetically, so the only way to sort them is by prepending a number. You can do &lt;code&gt;0. Today&lt;/code&gt; instead of &lt;code&gt;Today&lt;/code&gt;. It&#39;s good to do big increments between numbers, so the next report could be &lt;code&gt;10. Backlog&lt;/code&gt;. That way if you later realize you want another report between Today and Backlog, you can use &lt;code&gt;5. New Report&lt;/code&gt; and not rename all the reports.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/openproject/#pasting-text-into-the-descriptions&#34;&gt;Pasting text into the descriptions.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;When I paste the content of the clipboard in the description, all new lines are removed (&lt;code&gt;\n&lt;/code&gt;), the workaround is to paste it inside a &lt;code&gt;code snippet&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;task-management-workflows&#34;&gt;&lt;a href=&#34;life_planning.md&#34;&gt;Task Management Workflows&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;Correction: Update the task workflow of the month, and week plannings.&lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Update the workflows.&lt;/p&gt; &lt;p&gt;To suggest to use a script to follow them&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;life-review&#34;&gt;&lt;a href=&#34;life_review.md&#34;&gt;Life review&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: How to review your life.&lt;/p&gt; &lt;p&gt;Sometimes is good to stop, get into your cave and do an introspection on how is your life going.&lt;/p&gt; &lt;p&gt;I like to do this exercise the last week of the year. Although I&#39;d like to do it at least twice a year.&lt;/p&gt; &lt;p&gt;This article is the checklist I follow to do my life review, it may seem a lot to you or maybe very simple. You can take it as a base or maybe to get some ideas and then create your own that fits your needs.&lt;/p&gt; &lt;p&gt;The process then has many phases:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;life_review.md#housekeeping&#34;&gt;Housekeeping&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;life_review.md#analysis&#34;&gt;Analysis&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;life_review.md#planning&#34;&gt;Planning&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;news-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/news_management/&#34;&gt;News Management&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce news management.&lt;/p&gt; &lt;p&gt;The information world of today is overwhelming. It can reach a point that you just want to disconnect so as to avoid the continuous bombardment, but that leads to loosing connection with what&#39;s happening in the world. Without knowing what&#39;s going on it&#39;s impossible to act to shape it better.&lt;/p&gt; &lt;p&gt;I&#39;ve started analyzing how to filter the content.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/news_management/#workflow&#34;&gt;News management workflow explained.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;calendar-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/calendar_management/&#34;&gt;Calendar Management&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Calendar Management.&lt;/p&gt; &lt;p&gt;Since the break of my taskwarrior instance I&#39;ve used a physical calendar to manage the tasks that have a specific date. Can&#39;t wait for the first version of &lt;a href=&#34;https://github.com/lyz-code/pydo&#34;&gt;&lt;code&gt;pydo&lt;/code&gt;&lt;/a&gt; to be finished.&lt;/p&gt; &lt;p&gt;The next factors made me search for a temporal solution:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;It&#39;s taking longer than expected.&lt;/li&gt; &lt;li&gt;I&#39;ve started using a nextcloud calendar with some friends.&lt;/li&gt; &lt;li&gt;I frequently use Google calendar at work.&lt;/li&gt; &lt;li&gt;I&#39;m sick of having to log in Nexcloud and Google to get the day&#39;s appointments.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;To fulfill my needs the solution needs to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Import calendar events from different sources, basically through the &lt;a href=&#34;http://en.wikipedia.org/wiki/CalDAV&#34;&gt;CalDAV&lt;/a&gt; protocol.&lt;/li&gt; &lt;li&gt;Have a usable terminal user interface&lt;/li&gt; &lt;li&gt;Optionally have a command line interface or python library so it&#39;s easy to make scripts.&lt;/li&gt; &lt;li&gt;Optionally it can be based in python so it&#39;s easy to contribute&lt;/li&gt; &lt;li&gt;Support having a personal calendar mixed with the shared ones.&lt;/li&gt; &lt;li&gt;Show all calendars in the same interface&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Looking at the available programs I found &lt;a href=&#34;https://lyz-code.github.io/blue-book/khal/&#34;&gt;&lt;code&gt;khal&lt;/code&gt;&lt;/a&gt;, which looks like it may be up to the task.&lt;/p&gt; &lt;p&gt;Go through the &lt;a href=&#34;https://lyz-code.github.io/blue-book/khal/#installation&#34;&gt;installation&lt;/a&gt; steps and configure the instance to have a local calendar.&lt;/p&gt; &lt;p&gt;If you want to sync your calendar events through CalDAV, you need to set &lt;a href=&#34;https://lyz-code.github.io/blue-book/vdirsyncer/&#34;&gt;vdirsyncer&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;food-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/food_management/&#34;&gt;Food Management&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce my food management workflow.&lt;/p&gt; &lt;p&gt;As humans diet is an important factor in our health, we need to eat daily around three times a day, as such, each week we need to invest time into managing how to get food in front of us. Tasks like thinking what do you want to eat, buying the ingredients and cooking them make use a non negligible amount of time. Also something to keep in mind, is that eating is one of the great pleasures in our lives, so doing it poorly is a waste. The last part of the equation is that to eat good you either need time or money.&lt;/p&gt; &lt;p&gt;This article explores my thoughts and findings on how to optimize the use of time, money and mental load in food management while keeping the desired level of quality to enjoy each meal, being healthy and following the principles of ecology and sustainability. I&#39;m no expert at all on either of these topics. I&#39;m learning and making my mind while writing these lines.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;grocy-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/grocy_management/&#34;&gt;Grocy Management&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce my grocy management workflow.&lt;/p&gt; &lt;p&gt;Buying stuff is an unpleasant activity that drains your energy and time, it&#39;s the main perpetrator of the broken capitalist system, but sadly we have to yield to survive.&lt;/p&gt; &lt;p&gt;This article explores my thoughts and findings on how to optimize the use of time, money and mental load in grocy management to have enough stuff stored to live, while following the principles of ecology and sustainability. I&#39;m no expert at all on either of these topics. I&#39;m learning and making my mind while writing these lines.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://grocy.info/&#34;&gt;grocy&lt;/a&gt; is a web-based self-hosted groceries &amp;amp; household management solution for your home.&lt;/p&gt; &lt;p&gt;It is really easy to deploy if you know how to use &lt;a href=&#34;https://en.wikipedia.org/wiki/Docker_%28software%29&#34;&gt;Docker&lt;/a&gt;. The hard part comes when you do the initial load, as you have to add all the:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;User attributes.&lt;/li&gt; &lt;li&gt;Product locations.&lt;/li&gt; &lt;li&gt;Product groups.&lt;/li&gt; &lt;li&gt;Quantity conversions.&lt;/li&gt; &lt;li&gt;Products.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;health&#34;&gt;Health&lt;/h2&gt; &lt;h3 id=&#34;sleep&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/sleep/&#34;&gt;Sleep&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/sleep/#how-your-brain-generates-sleep&#34;&gt;How your brain generates sleep.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Brainwave activity of REM sleep looks similar to the one you have when you&#39;re awake. They cycle (going up and down) at a fast frequency of thirty or forty times per second in an unreliable pattern. This behaviour is explained by the fact that different parts of your waking brain are processing different pieces of information at different moments in time and in different ways.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;coding&#34;&gt;Coding&lt;/h2&gt; &lt;h3 id=&#34;learning-to-code&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/code_learning/&#34;&gt;Learning to code&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce guidelines to learn how to code.&lt;/p&gt; &lt;p&gt;Learning to code is a never ending, rewarding, frustrating, enlightening task. In this article you can see what is the generic roadmap (in my personal opinion) of a developer. As each of us is different, probably a generic roadmap won&#39;t suit your needs perfectly, if you are new to coding, I suggest you find a &lt;a href=&#34;https://lyz-code.github.io/blue-book/mentoring/&#34;&gt;mentor&lt;/a&gt; so you can both tweak it to your case.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/code_learning/#git&#34;&gt;Suggest a workflow to learn Git.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/git/&#34;&gt;Git&lt;/a&gt; is a software for tracking changes in any set of files, usually used for coordinating work among programmers collaboratively developing source code during software development. Its goals include speed, data integrity, and support for distributed, non-linear workflows (thousands of parallel branches running on different systems).&lt;/p&gt; &lt;p&gt;Git is a tough nut to crack, no matter how experience you are you&#39;ll frequently get surprised. Sadly it&#39;s one of the main tools to develop your code, so you must master it as soon as possible.&lt;/p&gt; &lt;p&gt;I&#39;ve listed you some resources &lt;a href=&#34;https://lyz-code.github.io/blue-book/git/?h=git#learning-git&#34;&gt;here&lt;/a&gt; on how to start. From that article I think it&#39;s also interesting that you read about:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/git/?h=git#pull-request-process&#34;&gt;Pull Request process&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/git/?h=git#git-workflow&#34;&gt;Git workflow&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;frontend-developer&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/frontend_learning/&#34;&gt;Frontend developer&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce guidelines to learn how to become a frontend developer.&lt;/p&gt; &lt;p&gt;This section is the particularization of the &lt;a href=&#34;https://lyz-code.github.io/blue-book/code_learning/&#34;&gt;Development learning article&lt;/a&gt; for a frontend developer, in particular a &lt;a href=&#34;https://lyz-code.github.io/blue-book/vuejs/&#34;&gt;Vue&lt;/a&gt; developer.&lt;/p&gt; &lt;p&gt;A Front-End Developer is someone who creates websites and web applications. It&#39;s main responsibility is to create what the user sees.&lt;/p&gt; &lt;p&gt;The basic languages for Front-End Development are &lt;a href=&#34;https://lyz-code.github.io/blue-book/html/&#34;&gt;HTML&lt;/a&gt;, &lt;a href=&#34;https://lyz-code.github.io/blue-book/css/&#34;&gt;CSS&lt;/a&gt;, and &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/javascript/javascript/&#34;&gt;JavaScript&lt;/a&gt;. Nowadays writing interfaces with only the basic languages makes no sense as there are other languages and frameworks that make better and quicker solutions. One of them is &lt;a href=&#34;https://lyz-code.github.io/blue-book/vuejs/&#34;&gt;Vue&lt;/a&gt;, which is the one I learnt, so the whole document will be focused on this path, nevertheless there are others popular ones like: &lt;a href=&#34;https://www.w3schools.com/whatis/whatis_bootstrap.asp&#34;&gt;Bootstrap&lt;/a&gt;, &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/react/react/&#34;&gt;React&lt;/a&gt;, &lt;a href=&#34;https://www.w3schools.com/jquery/default.asp&#34;&gt;jQuery&lt;/a&gt; or &lt;a href=&#34;https://www.w3schools.com/jquery/default.asp&#34;&gt;Angular&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;The difference between Front-End and Back-End is that Front-End refers to how a web page looks, while back-end refers to how it works.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;languages&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vuejs/&#34;&gt;Languages&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;New: Sum up the VueJS tutorial.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce Cypress.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.cypress.io/&#34;&gt;Cypress&lt;/a&gt; is a next generation front end testing tool built for the modern web.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce Vite.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://vitejs.dev/guide/&#34;&gt;Vite&lt;/a&gt; is a build tool that aims to provide a faster and leaner development experience for modern web projects. It consists of two major parts:&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;A dev server that provides rich feature enhancements over native ES modules, for example extremely fast Hot Module Replacement (HMR).&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;A build command that bundles your code with Rollup, pre-configured to output highly optimized static assets for production.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Vite is opinionated and comes with sensible defaults out of the box, but is also highly extensible via its Plugin API and JavaScript API with full typing support.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce Vitest.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://vitest.dev/&#34;&gt;Vitest&lt;/a&gt; is a blazing fast unit-test framework powered by Vite.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vue_snippets/#display-time-ago-from-timestamp&#34;&gt;Display time ago from timestamp.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use &lt;a href=&#34;https://vue2-timeago.netlify.app/guide/timeago/timeago.html&#34;&gt;vue2-timeago&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Install with:&lt;/p&gt;  &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce Vuetify.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://vuetifyjs.com/en/&#34;&gt;Vuetify&lt;/a&gt; is a Vue UI Library with beautifully handcrafted Material Components.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Sum up all Cypress documentation.&lt;/p&gt; &lt;p&gt;In particular how to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Install it&lt;/li&gt; &lt;li&gt;Write tests&lt;/li&gt; &lt;li&gt;Setup the tests&lt;/li&gt; &lt;li&gt;Do component testing&lt;/li&gt; &lt;li&gt;Do visual regression testing&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vue_snippets/#truncate-text-given-a-height&#34;&gt;Truncate text given a height.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;By default css is able to truncate text with the size of the screen but only on one line, if you want to fill up a portion of the screen (specified in number of lines or height css parameter) and then truncate all the text that overflows, you need to use &lt;a href=&#34;https://vue-clamp.vercel.app/&#34;&gt;vue-clamp&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vuejs/#environment-variables&#34;&gt;Environment variables.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you&#39;re using Vue 3 and Vite you can use &lt;a href=&#34;https://vitejs.dev/guide/env-and-mode.html&#34;&gt;the environment variables&lt;/a&gt; by defining them in &lt;code&gt;.env&lt;/code&gt; files.&lt;/p&gt; &lt;p&gt;You can specify environment variables by placing the following files in your project root:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;.env&lt;/code&gt;: Loaded in all cases.&lt;/li&gt; &lt;li&gt;&lt;code&gt;.env.local&lt;/code&gt;: Loaded in all cases, ignored by git.&lt;/li&gt; &lt;li&gt;&lt;code&gt;.env.[mode]&lt;/code&gt;: Only loaded in specified mode.&lt;/li&gt; &lt;li&gt;&lt;code&gt;.env.[mode].local&lt;/code&gt;: Only loaded in specified mode, ignored by git.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;An env file simply contains &lt;code&gt;key=value&lt;/code&gt; pairs of environment variables, by default only variables that start with &lt;code&gt;VITE_&lt;/code&gt; will be exposed.:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;DB_PASSWORD=foobar
VITE_SOME_KEY=123
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Only &lt;code&gt;VITE_SOME_KEY&lt;/code&gt; will be exposed as &lt;code&gt;import.meta.env.VITE_SOME_KEY&lt;/code&gt; to your client source code, but &lt;code&gt;DB_PASSWORD&lt;/code&gt; will not. So for example in a component you can use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;export default {
  props: {},
  mounted() {
    console.log(import.meta.env.VITE_SOME_KEY)
  },
  data: () =&amp;gt; ({
  }),
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vuejs/#deploying&#34;&gt;Deploy with docker.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;And fight to make the environment variables of the docker work, the problem is that these environment variables are set at build time, and can&#39;t be changed at runtime by default, so you can&#39;t offer a generic fronted Docker and particularize for the different cases. I&#39;ve literally cried for hours trying to find a solution for this until &lt;a href=&#34;https://medium.com/js-dojo/vue-js-runtime-environment-variables-807fa8f68665&#34;&gt;José Silva came to my rescue&lt;/a&gt;. The tweak is to use a docker entrypoint to inject the values we want.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vuetify/#testing&#34;&gt;Testing.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I tried doing component tests with Jest, &lt;a href=&#34;https://lyz-code.github.io/blue-book/vitest/&#34;&gt;Vitest&lt;/a&gt; and &lt;a href=&#34;https://lyz-code.github.io/blue-book/cypress/&#34;&gt;Cypress&lt;/a&gt; and found no way of making component tests, they all fail one way or the other.&lt;/p&gt; &lt;p&gt;E2E tests worked with Cypress however, that&#39;s going to be my way of action till this is solved.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add Cypress commands.&lt;/p&gt; &lt;p&gt;For the functions you write a lot you can use commands in &lt;code&gt;/cypress/support/commands.ts&lt;/code&gt;.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nx&#34;&gt;Cypress&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Commands&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;getById&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;selector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`[data-cy=&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;selector&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;]`&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;

&lt;span class=&#34;nx&#34;&gt;Cypress&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Commands&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;getByIdLike&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;selector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`[data-cy*=&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;selector&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;]`&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;

&lt;span class=&#34;nx&#34;&gt;Cypress&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Commands&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;findById&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;prevSubject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;selector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;find&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`[data-cy=&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;selector&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;]`&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;So you can now do &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getById&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;submit&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/cypress/#select-by-position-in-list&#34;&gt;Add more ways to select elements.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Select by position in list&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Inside our list, we can select elements based on their position in the list, using &lt;code&gt;.first()&lt;/code&gt;, &lt;code&gt;.last()&lt;/code&gt; or &lt;code&gt;.eq()&lt;/code&gt; selector.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;li&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;first&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// select &#34;red&#34;&lt;/span&gt;

&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;li&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;last&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// select &#34;violet&#34;&lt;/span&gt;

&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;li&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;eq&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// select &#34;yellow&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can also use &lt;code&gt;.next()&lt;/code&gt; and &lt;code&gt;.prev()&lt;/code&gt; to navigate through the elements.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Select elements by filtering&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Once you select multiple elements, you can filter within these based on another selector.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;li&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;filter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;.primary&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// select all elements with the class .primary&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To do the exact opposite, you can use &lt;code&gt;.not()&lt;/code&gt; command.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;li&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;not&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;.primary&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// select all elements without the class .primary&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/cypress/#finding-elements&#34;&gt;Finding elements.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can specify your selector by first selecting an element you want to search within, and then look down the DOM structure to find a specific element you are looking for.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;.list&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;find&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;.violet&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// finds an element with class .violet inside .list element&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Instead of looking down the DOM structure and finding an element within another element, we can look up. In this example, we first select our list item, and then try to find an element with a &lt;code&gt;.list&lt;/code&gt; class.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;.violet&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;parent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;.list&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// finds an element with class .list that is above our .violet element&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/cypress/#asserting-about-elements&#34;&gt;Assert on the content of an attribute.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;a&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;invoke&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;attr&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;href&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;should&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;eq&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;https://docs.cypress.io&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/cypress/#use-the-content-of-a-fixture-set-in-a-hook-in-a-test&#34;&gt;Use the content of a fixture set in a hook in a test.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you store and access the fixture data using this test context object, make sure to use &lt;code&gt;function () { ... }&lt;/code&gt; callbacks both for the hook and the test. Otherwise the test engine will NOT have this pointing at the test context.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nx&#34;&gt;describe&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;User page&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;beforeEach&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// &#34;this&#34; points at the test context object&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fixture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;user&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;then&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// &#34;this&#34; is still the test context object&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;user&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// the test callback is in &#34;function () { ... }&#34; form&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;it&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;has user&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// this.user exists&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;expect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;firstName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;to&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;equal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Jane&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/cypress/#issues&#34;&gt;Run only failing tests.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Cypress doesn&#39;t &lt;a href=&#34;https://github.com/cypress-io/cypress/issues/4886&#34;&gt;Allow to rerun failed tests&lt;/a&gt; but you can use &lt;code&gt;it.only&lt;/code&gt; on the test you want to run.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vuejs/#make-http-requests&#34;&gt;Make HTTP requests with Vue.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Compare &lt;a href=&#34;https://lyz-code.github.io/blue-book/vuejs/#fetch-api&#34;&gt;Fetch API&lt;/a&gt; and &lt;a href=&#34;https://lyz-code.github.io/blue-book/vuejs/#axios&#34;&gt;Axios&lt;/a&gt; when doing http requests to external services.&lt;/p&gt; &lt;p&gt;Explain how to do them with both methods and arrive to the conclusion that if you’re working on multiple requests, you’ll find that Fetch requires you to write more code than Axios, even when taking into consideration the setup needed for it. Therefore, for simple requests, Fetch API and Axios are quite the same. However, for more complex requests, Axios is better as it allows you to configure multiple requests in one place.&lt;/p&gt; &lt;p&gt;If you&#39;re making a simple request use the Fetch API, for the other cases use axios because:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;It allows you to configure multiple requests in one place&lt;/li&gt; &lt;li&gt;Code is shorter.&lt;/li&gt; &lt;li&gt;It allows you to &lt;a href=&#34;https://medium.com/bb-tutorials-and-thoughts/how-to-make-api-calls-in-vue-js-applications-43e017d4dc86&#34;&gt;place all the API calls under services so that these can be reused across components wherever they are needed&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;It&#39;s easy to set a timeout of the request.&lt;/li&gt; &lt;li&gt;It supports HTTP interceptors by befault&lt;/li&gt; &lt;li&gt;It does automatic JSON data transformation.&lt;/li&gt; &lt;li&gt;It&#39;s supported by old browsers, although you can bypass the problem with fetch too.&lt;/li&gt; &lt;li&gt;It has a progress indicator for large files.&lt;/li&gt; &lt;li&gt;Supports simultaneous requests by default.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Axios provides an easy-to-use API in a compact package for most of your HTTP communication needs. However, if you prefer to stick with native APIs, nothing stops you from implementing Axios features.&lt;/p&gt; &lt;p&gt;For more information read:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://medium.com/bb-tutorials-and-thoughts/how-to-make-api-calls-in-vue-js-applications-43e017d4dc86&#34;&gt;How To Make API calls in Vue.JS Applications by Bhargav Bachina&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://blog.logrocket.com/axios-vs-fetch-best-http-requests/&#34;&gt;Axios vs. fetch(): Which is best for making HTTP requests? by Faraz Kelhini&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/cypress/#simulate-errors&#34;&gt;Simulate errors.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nx&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Errors&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;errorMsg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Oops! Try again later&#39;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;it&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;simulates a server error&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;intercept&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;GET&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;**/search?query=cypress&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;statusCode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;500&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;as&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;getServerFailure&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;visit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;https://example.com/search&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;[data-cy=&#34;search-field&#34;]&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;should&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;be.visible&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;cypress{enter}&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;wait&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;@getServerFailure&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;contains&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;errorMsg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;should&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;be.visible&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;it&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;simulates a network failure&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;intercept&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;GET&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;**/search?query=cypressio&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;forceNetworkError&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;as&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;getNetworkFailure&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;visit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;https://example.com/search&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;[data-cy=&#34;search-field&#34;]&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;should&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;be.visible&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;cypressio{enter}&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;wait&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;@getNetworkFailure&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;contais&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;errorMsg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;should&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;be.visible&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vuejs/#handling-errors&#34;&gt;Handling errors doing requests to other endpoints.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To catch errors when doing requests you could use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;res&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;await&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;axios&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;/my-api-route&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Work with the response...&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;catch&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// The client was given an error response (5xx, 4xx)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// The client never received a response, and the request was never left&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Anything else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Error&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The differences in the &lt;code&gt;error&lt;/code&gt; object, indicate where the request encountered the issue.&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;&lt;code&gt;error.response&lt;/code&gt;: If your &lt;code&gt;error&lt;/code&gt; object has a &lt;code&gt;response&lt;/code&gt; property, it means that your server returned a 4xx/5xx error. This will assist you choose what sort of message to return to users.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;code&gt;error.request&lt;/code&gt;: This error is caused by a network error, a hanging backend that does not respond instantly to each request, unauthorized or cross-domain requests, and lastly if the backend API returns an error.&lt;/p&gt; &lt;p&gt;This occurs when the browser was able to initiate a request but did not receive a valid answer for any reason.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Other errors: It&#39;s possible that the &lt;code&gt;error&lt;/code&gt; object does not have either a &lt;code&gt;response&lt;/code&gt; or &lt;code&gt;request&lt;/code&gt; object attached to it. In this case it is implied that there was an issue in setting up the request, which eventually triggered an error.&lt;/p&gt; &lt;p&gt;For example, this could be the case if you omit the URL parameter from the &lt;code&gt;.get()&lt;/code&gt; call, and thus no request was ever made.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vuetify/#flex&#34;&gt;Use Flexbox with Vuetify.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Control the layout of flex containers with alignment, justification and more with responsive flexbox utilities.&lt;/p&gt; &lt;div class=&#34;admonition note&#34;&gt; &lt;p class=&#34;admonition-title&#34;&gt;Note&lt;/p&gt; &lt;pre&gt;&lt;code&gt;&#34;I suggest you use this page only as a reference, if it&#39;s the first time
you see this content, it&#39;s better to see it at the
[source](https://vuetifyjs.com/en/styles/flex) as you can see Flex in
action at the same time you read, which makes it much more easy to
understand.&#34;
&lt;/code&gt;&lt;/pre&gt; &lt;/div&gt; &lt;p&gt;Explain how to use:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vuetify/#display-breakpoints&#34;&gt;Display breakpoints&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vuetify/#flex-direction&#34;&gt;Flex direction&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vuetify/#flex-justify&#34;&gt;Flex justify&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vuetify/#flex-align&#34;&gt;Flex align&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vuetify/#margins&#34;&gt;Margins&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vuetify/#position-elements-with-flex&#34;&gt;Position elements with Flex&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vuetify/#Keep-the-structure-even-if-some-components-are-hidden&#34;&gt;Keep the structure even if some components are hidden&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vuetify/#illustrations&#34;&gt;Illustrations.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can get nice illustrations for your web on &lt;a href=&#34;https://drawkit.com&#34;&gt;Drawkit&lt;/a&gt;, for example I like to use the &lt;a href=&#34;https://drawkit.com/product/drawkit-classic&#34;&gt;Classic kit&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Correct the way to test for an attribute of an html element.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;a&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;should&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;have.attr&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;href&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;https://docs.cypress.io&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;and&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;have.attr&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;target&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;_blank&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Test it&#39;s meant to be opened&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// another tab&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/cypress/#sending-different-responses&#34;&gt;Sending different responses.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To return different responses from a single &lt;code&gt;GET /todos&lt;/code&gt; intercept, you can place all prepared responses into an array, and then use Array.prototype.shift to return and remove the first item.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nx&#34;&gt;it&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;returns list with more items on page reload&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;replies&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fixture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;articles.json&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;statusCode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;404&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;cy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;intercept&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;GET&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;/api/inbox&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;req&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;req&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;reply&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;replies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;shift&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()))&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vue_snippets/#get-assets-url&#34;&gt;Get assets url.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you&#39;re using Vite, you can save the assets such as images or audios in the &lt;code&gt;src/assets&lt;/code&gt; directory, and you can get the url with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nx&#34;&gt;getImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;ow&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;URL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`../assets/pictures/&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;active_id&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;.jpg`&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;import&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;meta&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;href&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This way it will give you the correct url whether you&#39;re in the development environment or in production.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vue_snippets/#play-audio-files&#34;&gt;Play audio files.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can get the file and save it into a &lt;code&gt;data&lt;/code&gt; element with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nx&#34;&gt;getAudio&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;audio&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;ow&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Audio&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ow&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;URL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`../assets/audio/&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;active_id&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;.mp3`&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;import&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;meta&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;href&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can start playing with &lt;code&gt;this.audio.play()&lt;/code&gt;, and stop with &lt;code&gt;this.audio.pause()&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vuejs/#vue-router&#34;&gt;Vue Router.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Creating a Single-page Application with Vue + Vue Router feels natural, all we need to do is map our components to the routes and let Vue Router know where to render them.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vuejs/#deploy-static-site-on-github-pages&#34;&gt;Deploy static site on github pages.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vuetify/#themes&#34;&gt;Themes.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Vuetify comes with two themes pre-installed, light and dark. To set the default theme of your application, use the &lt;code&gt;defaultTheme&lt;/code&gt; option.&lt;/p&gt; &lt;div class=&#34;admonition note&#34;&gt; &lt;p class=&#34;admonition-title&#34;&gt;File: &lt;code&gt;src/plugins/vuetify.js&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;import&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;createApp&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;from&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;vue&#39;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;import&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;createVuetify&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;from&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;vuetify&#39;&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;createVuetify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;theme&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;defaultTheme&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;dark&#39;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/div&gt; &lt;p&gt;Adding new themes is as easy as defining a new property in the &lt;code&gt;theme.themes&lt;/code&gt; object. A theme is a collection of colors and options that change the overall look and feel of your application. One of these options designates the theme as being either a light or dark variation. This makes it possible for Vuetify to implement Material Design concepts such as elevated surfaces having a lighter overlay color the higher up they are.&lt;/p&gt; &lt;div class=&#34;admonition note&#34;&gt; &lt;p class=&#34;admonition-title&#34;&gt;File: &lt;code&gt;src/plugins/vuetify.js&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;import&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;createApp&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;from&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;vue&#39;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;import&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;createVuetify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ThemeDefinition&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;from&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;vuetify&#39;&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;createVuetify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;theme&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;defaultTheme&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;myCustomLightTheme&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;themes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;myCustomLightTheme&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;dark&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;colors&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;background&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;#FFFFFF&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;surface&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;#FFFFFF&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;primary&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;#510560&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;primary-darken-1&#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;#3700B3&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;secondary&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;#03DAC6&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;secondary-darken-1&#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;#018786&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;#B00020&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;#2196F3&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;success&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;#4CAF50&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;warning&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;#FB8C00&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/div&gt; &lt;p&gt;To dynamically change theme during runtime.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;template&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;v&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;app&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;v&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;btn&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;click&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;toggleTheme&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;toggle&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;theme&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;/v-btn&amp;gt;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;/v-app&amp;gt;&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;/template&amp;gt;&lt;/span&gt;

&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;script&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;import&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;useTheme&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;from&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;vuetify&#39;&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;theme&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;useTheme&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;theme&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;toggleTheme&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;theme&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;global&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;theme&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;global&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;dark&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;light&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;dark&#39;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Most components support the &lt;code&gt;theme&lt;/code&gt; prop. When used, a new context is created for that specific component and all of its children. In the following example, the &lt;code&gt;v-btn&lt;/code&gt; uses the dark theme applied by its parent &lt;code&gt;v-card&lt;/code&gt;.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;template&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;v&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;app&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;v&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;card&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;theme&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;dark&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;&amp;lt;!--&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;button&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;dark&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;theme&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;--&amp;gt;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;v&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;btn&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;/v-btn&amp;gt;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;/v-card&amp;gt;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;/v-app&amp;gt;&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vuetify/#elements&#34;&gt;Add more elements.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vuetify/#cards&#34;&gt;Cards&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vuetify/#carousels&#34;&gt;Carousels&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vue_snippets/#apply-a-style-to-a-component-given-a-condition&#34;&gt;Apply a style to a component given a condition.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;if you use &lt;code&gt;:class&lt;/code&gt; you can write javascript code in the value, for example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;b-form-radio&lt;/span&gt;
  &lt;span class=&#34;na&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;user-retrieve-language p-2&#34;&lt;/span&gt;
  &lt;span class=&#34;na&#34;&gt;:class&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{&#39;font-weight-bold&#39;: selected === language.key}&#34;&lt;/span&gt;
  &lt;span class=&#34;na&#34;&gt;v-for&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;language in languages&#34;&lt;/span&gt;
  &lt;span class=&#34;na&#34;&gt;v-model&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;selected&#34;&lt;/span&gt;
  &lt;span class=&#34;na&#34;&gt;:id&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;language.key&#34;&lt;/span&gt;
  &lt;span class=&#34;na&#34;&gt;:checked&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;selected === language.key&#34;&lt;/span&gt;
  &lt;span class=&#34;na&#34;&gt;:value&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;language.key&#34;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vuejs/#debug-jest-tests&#34;&gt;Debug Jest tests.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you&#39;re not developing in Visual code, running a debugger is not easy in the middle of the tests, so to debug one you can use &lt;code&gt;console.log()&lt;/code&gt; statements and when you run them with &lt;code&gt;yarn test:unit&lt;/code&gt; you&#39;ll see the traces.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;python&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/python/&#34;&gt;Python&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add the di library to explore.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.adriangb.com/di/0.36.0/&#34;&gt;di&lt;/a&gt;: a modern dependency injection system, modeled around the simplicity of FastAPI&#39;s dependency injection.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add humanize library.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/python-humanize/humanize&#34;&gt;humanize&lt;/a&gt;: This modest package contains various common humanization utilities, like turning a number into a fuzzy human-readable duration (&#34;3 minutes ago&#34;) or into a human-readable size or throughput.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add huey.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/coleifer/huey&#34;&gt;huey&lt;/a&gt; is a little task queue for python.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/python/#generators&#34;&gt;Generators.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Generator functions are a special kind of function that return a lazy iterator. These are objects that you can loop over like a list. However, unlike lists, lazy iterators do not store their contents in memory.&lt;/p&gt; &lt;p&gt;An example would be an infinite sequence generator&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;infinite_sequence&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;yield&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;num&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can use it as a list:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;infinite_sequence&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;     &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34; &#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;9&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;11&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;12&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;13&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;15&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;16&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;17&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;18&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;19&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;20&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;21&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;22&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;23&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;24&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;25&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;26&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;27&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;28&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;29&lt;/span&gt;
&lt;span class=&#34;mi&#34;&gt;30&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;31&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;32&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;33&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;34&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;35&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;36&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;37&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;38&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;39&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;40&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;41&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;42&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Instead of using a &lt;code&gt;for&lt;/code&gt; loop, you can also call &lt;code&gt;next()&lt;/code&gt; on the generator object directly. This is especially useful for testing a generator in the console:.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;infinite_sequence&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/#do-the-remainder-or-modulus-of-a-number&#34;&gt;Do the remainder or modulus of a number.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;expr&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;%&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/#update-a-json-file-with-jq&#34;&gt;Update a json file with jq.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Save the next snippet to a file, for example &lt;code&gt;jqr&lt;/code&gt; and add it to your &lt;code&gt;$PATH&lt;/code&gt;.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;query&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$1&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$2&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;temp_file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;mktemp&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

jq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$query&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$file&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$temp_file&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

cmp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$file&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$temp_file&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$?&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-eq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;/bin/rm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$temp_file&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;/bin/mv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$temp_file&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$file&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Imagine you have the next json file:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;property&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;other_property&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;value&#34;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then you can run:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jqr&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;.property = false&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;status.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;And then you&#39;ll have:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;property&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;other_property&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;value&#34;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/python/#interesting-sources&#34;&gt;Interesting sources.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://musa-550-fall-2020.github.io/&#34;&gt;Musa 550&lt;/a&gt; looks like a nice way to learn how to process geolocation data.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pdm&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/asyncio/&#34;&gt;PDM&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Add asyncer as interesting library.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce PDM.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://pdm.fming.dev/&#34;&gt;PDM&lt;/a&gt; is a modern Python package manager with &lt;a href=&#34;https://www.python.org/dev/peps/pep-0582/&#34;&gt;PEP 582&lt;/a&gt; support. It installs and manages packages in a similar way to npm that doesn&#39;t need to create a virtualenv at all!&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Note that &lt;code&gt;pdm update&lt;/code&gt; doesn&#39;t upgrade the constrains in &lt;code&gt;pyproject.toml&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add tutorial on how to use asyncio.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.roguelynn.com/words/asyncio-we-did-it-wrong/&#34;&gt;Roguelynn tutorial&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Version overriding now supports constrains.&lt;/p&gt; &lt;p&gt;Before you had to pin specific versions, which is not maintainable, now you can use constrains&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[tool.pdm.overrides]&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;asgiref&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;&amp;gt;=3.2.10&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/pdm/#show-outdated-packages&#34;&gt;Show outdated packages.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pdm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--dry-run&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--unconstrained
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/javascript_snippets/#round-a-number&#34;&gt;Round a number.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;Math&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;round&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;2.5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/javascript_snippets/#remove-focus-from-element&#34;&gt;Remove focus from element.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;activeElement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;blur&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/javascript_snippets/#concatenate-two-arrays&#34;&gt;Concatenate two arrays.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kd&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;arr1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Cecilie&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Lone&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;arr2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Emil&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Tobias&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Linus&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;children&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;arr1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;concat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;arr2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To join more arrays you can use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kd&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;arr1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Cecilie&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Lone&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;arr2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Emil&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Tobias&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Linus&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;arr3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Robin&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;children&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;arr1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;concat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;arr2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;arr3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/javascript_snippets/#check-if-a-variable-is-not-undefined&#34;&gt;Check if a variable is not undefined.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ow&#34;&gt;typeof&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;lastname&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;undefined&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Hi. Variable is defined.&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; feat(vue_snippets#Run function in background): Run function in background&lt;/p&gt; &lt;p&gt;To achieve that you need to use &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/javascript/javascript/#timing-events&#34;&gt;the javascript method called &lt;code&gt;setInterval()&lt;/code&gt;&lt;/a&gt;. It’s a simple function that would repeat the same task over and over again. Here’s an example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;myFunction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;setInterval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(){&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Hello world&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;3000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you add a call to this method for any button and click on it, it will print Hello world every 3 seconds (3000 milliseconds) until you close the page.&lt;/p&gt; &lt;p&gt;In Vue you could do something like:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;script&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;inbox_retry&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;undefined&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}),&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;methods&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;retryGetInbox&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;inbox_retry&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;setInterval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;showError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Retrying the fetch of the inbox&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Add your code here.&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;clearInterval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;inbox_retry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;30000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can call &lt;code&gt;this.retryGetInbox()&lt;/code&gt; whenever you want to start running the function periodically. Once &lt;code&gt;this.showError&lt;/code&gt; is &lt;code&gt;false&lt;/code&gt;, we stop running the function with &lt;code&gt;clearInterval(this.inbox_retry)&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/javascript_snippets/#set-variable-if-it&#39;s-undefined&#34;&gt;Set variable if it&#39;s undefined.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;undefined&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;your_default_value&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/pdm/#supporting-pre-releases&#34;&gt;Supporting pre-releases.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To help package maintainers, you can allow pre-releases to be validate candidates, that way you&#39;ll get the issues sooner. It will mean more time to maintain the broken CIs if you update your packages daily (as you should!), but it&#39;s the least you can do to help your downstream library maintainers&lt;/p&gt; &lt;p&gt;By default, &lt;code&gt;pdm&lt;/code&gt;&#39;s dependency resolver will ignore prereleases unless there are no stable versions for the given version range of a dependency. This behavior can be changed by setting allow_prereleases to true in &lt;code&gt;[tool.pdm]&lt;/code&gt; table:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[tool.pdm]&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;allow_prereleases&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/pdm/#solve-circular-dependencies&#34;&gt;Solve circular dependencies.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Sometimes &lt;code&gt;pdm&lt;/code&gt; is not able to &lt;a href=&#34;https://github.com/pdm-project/pdm/issues/1354&#34;&gt;locate the best package combination&lt;/a&gt;, or it does too many loops, so to help it you can update your version constrains so that it has the minimum number of candidates.&lt;/p&gt; &lt;p&gt;To solve circular dependencies we first need to locate what are the conflicting packages, &lt;a href=&#34;https://github.com/pdm-project/pdm/issues/1354&#34;&gt;&lt;code&gt;pdm&lt;/code&gt; doesn&#39;t make it easy to detect them&lt;/a&gt;. Locate all the outdated packages by doing &lt;code&gt;pdm show&lt;/code&gt; on each package until &lt;a href=&#34;https://github.com/pdm-project/pdm/issues/1356&#34;&gt;this issue is solved&lt;/a&gt; and run &lt;code&gt;pdm update {package} --unconstrained&lt;/code&gt; for each of them. If you&#39;re already on the latest version, update your &lt;code&gt;pyproject.toml&lt;/code&gt; to match the latest state.&lt;/p&gt; &lt;p&gt;Once you have everything to the latest compatible version, you can try to upgrade the rest of the packages one by one to the latest with &lt;code&gt;--unconstrained&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;In the process of doing these steps you&#39;ll see some conflicts in the dependencies that can be manually solved by preventing those versions to be installed or maybe changing the &lt;code&gt;python-requires&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Suggest to use Asyncer.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://asyncer.tiangolo.com/tutorial/&#34;&gt;Asyncer&lt;/a&gt; looks very useful&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/pdm/#solve-circular-dependencies&#34;&gt;Solve circular dependencies by manual constraining.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It also helps to run &lt;code&gt;pdm update&lt;/code&gt; with the &lt;code&gt;-v&lt;/code&gt; flag, that way you see which are the candidates that are rejected, and you can put the constrain you want. For example, I was seeing the next traceback:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pdm.termui: Conflicts detected:
  pyflakes&amp;gt;=3.0.0 (from &amp;lt;Candidate autoflake 2.0.0 from https://pypi.org/simple/autoflake/&amp;gt;)
  pyflakes&amp;lt;2.5.0,&amp;gt;=2.4.0 (from &amp;lt;Candidate flake8 4.0.1 from unknown&amp;gt;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;So I added a new dependency to pin it:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[tool.pdm.dev-dependencies]
dependencies = [
    # Until flakeheaven supports flake8 5.x
    # https://github.com/flakeheaven/flakeheaven/issues/132
    &#34;flake8&amp;gt;=4.0.1,&amp;lt;5.0.0&#34;,
    &#34;pyflakes&amp;lt;2.5.0&#34;,
]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If none of the above works, you can override them:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[tool.pdm.overrides]
&#34;importlib-metadata&#34; = &#34;&amp;gt;=3.10&#34;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Suggest to use pydeps.&lt;/p&gt; &lt;p&gt;If you get lost in understanding your dependencies, you can try using &lt;a href=&#34;https://github.com/thebjorn/pydeps&#34;&gt;&lt;code&gt;pydeps&lt;/code&gt;&lt;/a&gt; to get your head around it.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;libraries&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/beautifulsoup/&#34;&gt;Libraries&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce BeautifulSoup and how to use it.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://beautiful-soup-4.readthedocs.io/en/latest/&#34;&gt;BeautifulSoup&lt;/a&gt; is a Python library for pulling data out of HTML and XML files. It works with your favorite parser to provide idiomatic ways of navigating, searching, and modifying the parse tree.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/beautifulsoup/#modifying-the-tree&#34;&gt;Modifying the tree.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;PageElement.replace_with()&lt;/code&gt; removes a tag or string from the tree, and replaces it with the tag or string of your choice:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;markup&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;a href=&#34;http://example.com/&#34;&amp;gt;I linked to &amp;lt;i&amp;gt;example.com&amp;lt;/i&amp;gt;&amp;lt;/a&amp;gt;&#39;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;soup&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;BeautifulSoup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;markup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;a_tag&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;soup&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;new_tag&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;soup&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new_tag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;b&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;new_tag&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;example.net&#34;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;a_tag&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;replace_with&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new_tag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;a_tag&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Sometimes it doesn&#39;t work. If it doesn&#39;t use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a_tag&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;clear&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;a_tag&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new_tag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce python gnupg.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/vsajip/python-gnupg&#34;&gt;python-gnupg&lt;/a&gt; is a Python library to interact with &lt;code&gt;gpg&lt;/code&gt; taking care of the internal details and allows its users to generate and manage keys, encrypt and decrypt data, and sign and verify messages.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/vsajip/python-gnupg#installing-from-pypi&#34;&gt;Installation&lt;/a&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;python-gnupg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;a href=&#34;https://gnupg.readthedocs.io/en/latest/#getting-started&#34;&gt;Usage&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;```python gpg = gnupg.GPG(gnupghome=&#34;/path/to/home/directory&#34;)&lt;/p&gt; &lt;p&gt;gpg.decrypt(&#34;path/to/file&#34;)&lt;/p&gt; &lt;p&gt;public_keys = gpg.list_keys() private_keys = gpg.list_keys(True)&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Use &lt;code&gt;decrypt_file&lt;/code&gt; instead of &lt;code&gt;decrypt&lt;/code&gt; for files.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;gpg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;decrypt_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;path/to/file&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Note: You can&#39;t pass &lt;code&gt;Path&lt;/code&gt; arguments to &lt;code&gt;decrypt_file&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;configure-docker-to-host-the-application&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/type_hints/&#34;&gt;Configure Docker to host the application&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/type_hints/#usage-of-ellipsis-on-tuple-type-hints&#34;&gt;Usage of ellipsis on &lt;code&gt;Tuple&lt;/code&gt; type hints.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The ellipsis is used to specify an arbitrary-length homogeneous tuples, for example &lt;code&gt;Tuple[int, ...]&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/boto3/#list-the-files-of-a-bucket&#34;&gt;List the files of a bucket.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Suggest to use &lt;code&gt;Sequence&lt;/code&gt; over &lt;code&gt;List&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Because using &lt;code&gt;List&lt;/code&gt; could lead to some unexpected errors when combined with type inference. For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;A&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;B&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;A&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;lst&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;A&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;A&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()]&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# Inferred type is List[A]&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;new_lst&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;B&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;B&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()]&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# inferred type is List[B]&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;lst&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new_lst&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# mypy will complain about this, because List is invariant&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Possible strategies in such situations are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Use an explicit type annotation:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;new_lst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;A&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;B&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;B&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()]&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;lst&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new_lst&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# OK&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Make a copy of the right hand side:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;lst&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new_lst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# Also OK&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Use immutable collections as annotations whenever possible:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;f_bad&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;A&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;A&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;f_bad&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new_lst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# Fails&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;f_good&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Sequence&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;A&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;A&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;f_good&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new_lst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# OK&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/type_hints/#overloading-the-methods&#34;&gt;Overloading the methods.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Sometimes the types of several variables are related, such as “if x is type A, y is type B, else y is type C”. Basic type hints cannot describe such relationships, making type checking cumbersome or inaccurate. We can instead use &lt;code&gt;@typing.overload&lt;/code&gt; to represent type relationships properly.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;__future__&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;annotations&lt;/span&gt;

&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;collections.abc&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Sequence&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;typing&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;overload&lt;/span&gt;

&lt;span class=&#34;nd&#34;&gt;@overload&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;double&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;input_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;

&lt;span class=&#34;nd&#34;&gt;@overload&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;double&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;input_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Sequence&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;double&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;input_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Sequence&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;input_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Sequence&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;input_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;input_&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This looks a bit weird at first glance—we are defining double three times! Let’s take it apart.&lt;/p&gt; &lt;p&gt;The first two &lt;code&gt;@overload&lt;/code&gt; definitions exist only for their type hints. Each definition represents an allowed combination of types. These definitions never run, so their bodies could contain anything, but it’s idiomatic to use Python’s &lt;code&gt;...&lt;/code&gt; (ellipsis) literal.&lt;/p&gt; &lt;p&gt;The third definition is the actual implementation. In this case, we need to provide type hints that union all the possible types for each variable. Without such hints, Mypy will skip type checking the function body.&lt;/p&gt; &lt;p&gt;When Mypy checks the file, it collects the &lt;code&gt;@overload&lt;/code&gt; definitions as type hints. It then uses the first non-&lt;code&gt;@overload&lt;/code&gt; definition as the implementation. All &lt;code&gt;@overload&lt;/code&gt; definitions must come before the implementation, and multiple implementations are not allowed.&lt;/p&gt; &lt;p&gt;When Python imports the file, the &lt;code&gt;@overload&lt;/code&gt; definitions create temporary double functions, but each is overridden by the next definition. After importing, only the implementation exists. As a protection against accidentally missing implementations, attempting to call an &lt;code&gt;@overload&lt;/code&gt; definition will raise a &lt;code&gt;NotImplementedError&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;&lt;code&gt;@overload&lt;/code&gt; can represent arbitrarily complex scenarios. For a couple more examples, see the function overloading section of the &lt;a href=&#34;https://mypy.readthedocs.io/en/stable/more_types.html#function-overloading&#34;&gt;Mypy docs&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#start-request-repeated-too-quickly&#34;&gt;Debug the Start request repeated too quickly error.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use &lt;code&gt;journalctl -eu docker&lt;/code&gt; to debug&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Update TypeVars nomenclature.&lt;/p&gt; &lt;p&gt;Using &lt;code&gt;UserT&lt;/code&gt; is &lt;a href=&#34;https://github.com/PyCQA/pylint/issues/6003&#34;&gt;not supported by pylint&lt;/a&gt;, use &lt;code&gt;UserT&lt;/code&gt; instead.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/boto3/#ec2&#34;&gt;Add common ec2 functions.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/boto3/#get-instance-types&#34;&gt;Get instance types&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/boto3/#get-instance-prices&#34;&gt;Get instance prices&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/type_hints/#using-typing.cast&#34;&gt;Using &lt;code&gt;typing.cast&lt;/code&gt;.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Sometimes the type hints of your program don&#39;t work as you expect, if you&#39;ve given up on fixing the issue you can &lt;code&gt;# type: ignore&lt;/code&gt; it, but if you know what type you want to enforce, you can use &lt;a href=&#34;https://docs.python.org/3/library/typing.html#typing.cast&#34;&gt;&lt;code&gt;typing.cast()&lt;/code&gt;&lt;/a&gt; explicitly or implicitly from &lt;code&gt;Any&lt;/code&gt; with type hints. With casting we can force the type checker to treat a variable as a given type.&lt;/p&gt; &lt;p&gt;The main case to reach for &lt;code&gt;cast()&lt;/code&gt; are when the type hints for a module are either missing, incomplete, or incorrect. This may be the case for third party packages, or occasionally for things in the standard library.&lt;/p&gt; &lt;p&gt;Take this example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;datetime&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;dt&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;typing&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cast&lt;/span&gt;

&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;third_party&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;get_data&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;get_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;last_import_time&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cast&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;last_import_time&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Imagine &lt;code&gt;get_data()&lt;/code&gt; has a return type of &lt;code&gt;dict[str, Any]&lt;/code&gt;, rather than using stricter per-key types with a &lt;code&gt;TypedDict&lt;/code&gt;. From reading the documentation or source we might find that the &lt;code&gt;last_import_time&lt;/code&gt; key always contains a &lt;code&gt;datetime&lt;/code&gt; object. Therefore, when we access it, we can wrap it in a &lt;code&gt;cast()&lt;/code&gt;, to tell our type checker the real type rather than continuing with &lt;code&gt;Any&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;When we encounter missing, incomplete, or incorrect type hints, we can contribute back a fix. This may be in the package itself, its related stubs package, or separate stubs in Python’s typeshed. But until such a fix is released, we will need to use &lt;code&gt;cast()&lt;/code&gt; to make our code pass type checking.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#with-renovate&#34;&gt;Update dockers with Renovate.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/renovate/&#34;&gt;Renovate&lt;/a&gt; is a program that does automated dependency updates. Multi-platform and multi-language.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#connect-multiple-docker-compose-files&#34;&gt;Connect multiple docker compose files.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can connect services defined across multiple docker-compose.yml files.&lt;/p&gt; &lt;p&gt;In order to do this you’ll need to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Create an external network with &lt;code&gt;docker network create &amp;lt;network name&amp;gt;&lt;/code&gt;&lt;/li&gt; &lt;li&gt;In each of your &lt;code&gt;docker-compose.yml&lt;/code&gt; configure the default network to use your externally created network with the networks top-level key.&lt;/li&gt; &lt;li&gt;You can use either the service name or container name to connect between containers.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#attach-a-docker-to-many-networks&#34;&gt;Attach a docker to many networks.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can&#39;t do it through the &lt;code&gt;docker run&lt;/code&gt; command, there you can only specify one network. However, you can attach a docker to a network with the command:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;network&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;attach&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;network-name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker-name
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;click&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/click/&#34;&gt;Click&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/click/#file-system-isolation&#34;&gt;File System Isolation.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;For basic command line tools with file system operations, the &lt;code&gt;CliRunner.isolated_filesystem()&lt;/code&gt; method is useful for setting the current working directory to a new, empty folder.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;click.testing&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CliRunner&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;cat&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cat&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;test_cat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;runner&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CliRunner&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;runner&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isolated_filesystem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;hello.txt&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;w&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Hello World!&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

        &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;runner&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;invoke&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;hello.txt&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exit_code&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;output&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Hello World!&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Pass &lt;code&gt;temp_dir&lt;/code&gt; to control where the temporary directory is created. The directory will not be removed by Click in this case. This is useful to integrate with a framework like Pytest that manages temporary files.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;test_keep_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tmp_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;runner&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CliRunner&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;runner&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isolated_filesystem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;temp_dir&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tmp_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;td&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;dash&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/pydantic_factories/&#34;&gt;Dash&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Correct the type hints of the factory.&lt;/p&gt; &lt;p&gt;Use &lt;code&gt;Any&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;PersonFactory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ModelFactory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Any&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]):&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/pydantic_factories/#issues&#34;&gt;Track issue when using with.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/pydantic_factories/#creating-your-custom-factories&#34;&gt;Creating your custom factories.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If your model has an attribute that is not supported by &lt;code&gt;pydantic-factories&lt;/code&gt; and it depends on third party libraries, you can create your custom extension subclassing the &lt;code&gt;ModelFactory&lt;/code&gt;, and overriding the &lt;code&gt;get_mock_value&lt;/code&gt; method to add your logic.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;from pydantic_factories import ModelFactory

class CustomFactory(ModelFactory[Any]):
    &#34;&#34;&#34;Tweak the ModelFactory to add our custom mocks.&#34;&#34;&#34;

    @classmethod
    def get_mock_value(cls, field_type: Any) -&amp;gt; Any:
        &#34;&#34;&#34;Add our custom mock value.&#34;&#34;&#34;
        if str(field_type) == &#34;my_super_rare_datetime_field&#34;:
            return cls._get_faker().date_time_between()

        return super().get_mock_value(field_type)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where &lt;code&gt;cls._get_faker()&lt;/code&gt; is a &lt;code&gt;faker&lt;/code&gt; instance that you can use to build your returned value.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_code_styling/#w1514-set-encoding-on-open&#34;&gt;Solve W1514 pylint error.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;file.txt&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;r&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;encoding&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;utf-8&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Deprecate in favour of Streamlit.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://docs.streamlit.io/&#34;&gt;Streamlit&lt;/a&gt; is a much more easy, beautiful and clean library for the same purpose.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/python_sh/#running-in-background&#34;&gt;Running process in background.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;By default, each running command blocks until completion. If you have a long-running command, you can put it in the background with the &lt;code&gt;_bg=True&lt;/code&gt; special kwarg:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;sleep&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;...3 seconds later&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sleep&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_bg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;prints immediately!&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wait&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;...and 3 seconds later&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You’ll notice that you need to call &lt;code&gt;RunningCommand.wait()&lt;/code&gt; in order to exit after your command exits.&lt;/p&gt; &lt;p&gt;Commands launched in the background ignore &lt;code&gt;SIGHUP&lt;/code&gt;, meaning that when their controlling process (the session leader, if there is a controlling terminal) exits, they will not be signalled by the kernel. But because &lt;code&gt;sh&lt;/code&gt; commands launch their processes in their own sessions by default, meaning they are their own session leaders, ignoring &lt;code&gt;SIGHUP&lt;/code&gt; will normally have no impact. So the only time ignoring &lt;code&gt;SIGHUP&lt;/code&gt; will do anything is if you use &lt;code&gt;_new_session=False&lt;/code&gt;, in which case the controlling process will probably be the shell from which you launched python, and exiting that shell would normally send a &lt;code&gt;SIGHUP&lt;/code&gt; to all child processes.&lt;/p&gt; &lt;p&gt;If you want to terminate the process use &lt;code&gt;p.kill()&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/python_sh/#output-callbacks&#34;&gt;Output callbacks.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;In combination with &lt;code&gt;_bg=True&lt;/code&gt;, &lt;code&gt;sh&lt;/code&gt; can use callbacks to process output incrementally by passing a callable function to &lt;code&gt;_out&lt;/code&gt; and/or &lt;code&gt;_err&lt;/code&gt;. This callable will be called for each line (or chunk) of data that your command outputs:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;sh&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tail&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;process_output&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;line&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;line&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tail&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;-f&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;/var/log/some_log_file.log&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_out&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;process_output&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_bg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wait&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To “quit” your callback, simply &lt;code&gt;return True&lt;/code&gt;. This tells the command not to call your callback anymore. This does not kill the process though see &lt;a href=&#34;#interactive-callbacks&#34;&gt;Interactive callbacks&lt;/a&gt; for how to kill a process from a callback.&lt;/p&gt; &lt;p&gt;The line or chunk received by the callback can either be of type str or bytes. If the output could be decoded using the provided encoding, a str will be passed to the callback, otherwise it would be raw bytes.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;html&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/python_package_management/&#34;&gt;HTML&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Tweak Poetry evaluation and add PDM.&lt;/p&gt; &lt;p&gt;Check &lt;a href=&#34;https://lyz-code.github.io/blue-book/python_package_management/#pdm&#34;&gt;PDM&#39;s&lt;/a&gt; review, it&#39;s awesome!&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Sum up the W3 HTML tutorial.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/html/#html-beautifier&#34;&gt;HTML beautifier.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you encounter html code that it&#39;s not well indented you can use &lt;a href=&#34;https://htmlbeautify.com&#34;&gt;html beautify&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;css&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/css/&#34;&gt;CSS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Sum up the W3 CSS tutorial.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/css/#flexbox-layout&#34;&gt;CSS Flexbox layout.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The Flexbox Layout aims at providing a more efficient way to lay out, align and distribute space among items in a container, even when their size is unknown and/or dynamic.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;javascript&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/&#34;&gt;Javascript&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/#resolve-the-307-error&#34;&gt;Resolve the 307 error.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Probably you&#39;ve introduced an ending &lt;code&gt;/&lt;/code&gt; to the endpoint, so instead of asking for &lt;code&gt;/my/endpoint&lt;/code&gt; you tried to do &lt;code&gt;/my/endpoint/&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/#resolve-the-422-error&#34;&gt;Resolve the 422 error.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You&#39;re probably passing the wrong arguments to the POST request, to solve it see the &lt;code&gt;text&lt;/code&gt; attribute of the result. For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;post&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;/source/add&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;body&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The error is telling us that the required &lt;code&gt;url&lt;/code&gt; parameter is missing.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/#resolve-the-409-error&#34;&gt;Resolve the 409 error.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Probably an exception was raised in the backend, use &lt;code&gt;pdb&lt;/code&gt; to follow the trace and catch where it happened.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Use ternary conditional operator.&lt;/p&gt; &lt;p&gt;It&#39;s defined by a condition followed by a question mark &lt;code&gt;?&lt;/code&gt;, then an expression to execute if the condition is truthy followed by a colon &lt;code&gt;:&lt;/code&gt;, and finally the expression to execute if the condition is falsy.&lt;/p&gt; &lt;p&gt;&lt;code&gt;condition ? exprIfTrue : exprIfFalse&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getFee&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;isMember&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;isMember&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;$2.00&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;$10.00&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getFee&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;// expected output: &#34;$2.00&#34;&lt;/span&gt;

&lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getFee&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;// expected output: &#34;$10.00&#34;&lt;/span&gt;

&lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getFee&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;// expected output: &#34;$10.00&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/javascript/javascript/#filter-the-contents-of-an-array&#34;&gt;Filter the contents of an array.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The &lt;code&gt;filter()&lt;/code&gt; method creates a new array filled with elements that pass a test provided by a function.&lt;/p&gt; &lt;p&gt;The &lt;code&gt;filter()&lt;/code&gt; method does not execute the function for empty elements.&lt;/p&gt; &lt;p&gt;The &lt;code&gt;filter()&lt;/code&gt; method does not change the original array.&lt;/p&gt; &lt;p&gt;For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kd&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ages&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;32&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;33&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;16&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;40&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;filter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;checkAdult&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;

&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;checkAdult&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;age&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;18&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/javascript/javascript/#interacting-with-html&#34;&gt;Interacting with HTML.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/#add-endpoints-only-on-testing-environment&#34;&gt;Add endpoints only on testing environment.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Sometimes you want to have some API endpoints to populate the database for end to end testing the frontend. If your &lt;code&gt;app&lt;/code&gt; config has the &lt;code&gt;environment&lt;/code&gt; attribute, you could try to do:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;app&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FastAPI&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

&lt;span class=&#34;nd&#34;&gt;@lru_cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;get_config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Configure the program settings.&#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;# no cover: the dependency are injected in the tests&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Loading the config&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# pragma: no cover&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;get_config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;environment&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;testing&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;

    &lt;span class=&#34;nd&#34;&gt;@app&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;/seed&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;status_code&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;201&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;seed_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;repo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Repository&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Depends&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_repo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;empty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bool&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;num_articles&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;num_sources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Add seed data for the end to end tests.&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;        Args:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;            repo: Repository to store the data.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        &#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;repo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;repo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;empty&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;empty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;num_articles&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;num_articles&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;num_sources&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;num_sources&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;repo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;But the injection of the dependencies is only done inside the functions, so &lt;code&gt;get_config().environment&lt;/code&gt; will always be the default value. I ended up doing that check inside the endpoint, which is not ideal.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nd&#34;&gt;@app&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;/seed&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;status_code&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;201&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;seed_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Config&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Depends&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;repo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Repository&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Depends&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_repo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;empty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bool&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;num_articles&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;num_sources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Add seed data for the end to end tests.&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;    Args:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        repo: Repository to store the data.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    &#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;environment&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;testing&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;repo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HTTPException&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;status_code&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;404&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/javascript/javascript/#coalescent-operator&#34;&gt;Coalescent operator.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Is similar to the Logical &lt;code&gt;OR&lt;/code&gt; operator (&lt;code&gt;||&lt;/code&gt;), except instead of relying on truthy/falsy values, it relies on &#34;nullish&#34; values (there are only 2 nullish values, &lt;code&gt;null&lt;/code&gt; and &lt;code&gt;undefined&lt;/code&gt;).&lt;/p&gt; &lt;p&gt;This means it&#39;s safer to use when you treat falsy values like &lt;code&gt;0&lt;/code&gt; as valid.&lt;/p&gt; &lt;p&gt;Similar to Logical &lt;code&gt;OR&lt;/code&gt;, it functions as a control-flow operator; it evaluates to the first not-nullish value.&lt;/p&gt; &lt;p&gt;It was introduced in Chrome 80 / Firefox 72 / Safari 13.1. It has no IE support.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;??&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;// 4, since neither value is nullish&lt;/span&gt;
&lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;??&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;// 10, since &#39;null&#39; is nullish&lt;/span&gt;
&lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;undefined&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;??&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;// 0, since &#39;undefined&#39; is nullish&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;// Here&#39;s a case where it differs from&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;// Logical OR (||):&lt;/span&gt;
&lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;??&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 0&lt;/span&gt;
&lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;qwik&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/python_profiling/&#34;&gt;Qwik&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Added memray profiling tool.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://bloomberg.github.io/memray/&#34;&gt;memray&lt;/a&gt; looks very promising.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce Qwik.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://qwik.builder.io&#34;&gt;Qwik&lt;/a&gt; is a new kind of web framework that can deliver instantly load web applications at any size or complexity. Your sites and apps can boot with about 1kb of JS (regardless of application complexity), and achieve consistent performance at scale.&lt;/p&gt; &lt;p&gt;You can see a good overview in the &lt;a href=&#34;https://www.youtube.com/watch?v=0dC11DMR3fU&amp;amp;t=154s&#34;&gt;Qwik presentation&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;jwt&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/jwt/&#34;&gt;JWT&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce JWT.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/JSON_Web_Token&#34;&gt;JWT&lt;/a&gt; (JSON Web Token) is a proposed Internet standard for creating data with optional signature and/or optional encryption whose payload holds JSON that asserts some number of claims. The tokens are signed either using a private secret or a public/private key.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pytest&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/pytest_httpserver/&#34;&gt;Pytest&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce &lt;code&gt;pytest-httpserver&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://pytest-httpserver.readthedocs.io/en/latest/index.html&#34;&gt;pytest-httpserver&lt;/a&gt; is a python package which allows you to start a real HTTP server for your tests. The server can be configured programmatically to how to respond to requests.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/feedparser/#issues&#34;&gt;Add issue when using &lt;code&gt;updated_parser&lt;/code&gt;.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/kurtmckee/feedparser/issues/151&#34;&gt;Deprecation warning when using &lt;code&gt;updated_parsed&lt;/code&gt;&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Update the tmpdir_factory type hints.&lt;/p&gt; &lt;p&gt;You should now use &lt;code&gt;TempPathFactory&lt;/code&gt; instead of &lt;code&gt;TempdirFactory&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pytest/#global-usage&#34;&gt;Use &lt;code&gt;pytest-freezegun&lt;/code&gt; globally.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://medium.com/@boxed/flaky-tests-part-3-freeze-the-world-e4929a0da00e&#34;&gt;Most of the tests&lt;/a&gt; work with frozen time, so it&#39;s better to freeze it by default and unfreeze it on the ones that actually need time to move.&lt;/p&gt; &lt;p&gt;To do that set in your &lt;code&gt;tests/conftest.py&lt;/code&gt; a globally used fixture:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;TYPE_CHECKING&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;freezegun.api&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FrozenDateTimeFactory&lt;/span&gt;

&lt;span class=&#34;nd&#34;&gt;@pytest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fixture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;autouse&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;frozen_time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Generator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;FrozenDateTimeFactory&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Freeze all tests time&#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;freezegun&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;freeze_time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;freeze&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;yield&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;freeze&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Ignore a warning of a specific package.&lt;/p&gt; &lt;p&gt;In the &lt;code&gt;pyproject.toml&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;filterwarnings&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;error&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Until https://github.com/ktosiek/pytest-freezegun/issues/35 is merged&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;ignore::DeprecationWarning:pytest_freezegun.*&#34;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pytest/#run-tests-in-a-random-order&#34;&gt;Run tests in a random order.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;pytest-random-order&lt;/code&gt; is a pytest plugin that randomises the order of tests. This can be useful to detect a test that passes just because it happens to run after an unrelated test that leaves the system in a favourable state.&lt;/p&gt; &lt;p&gt;To use it add the &lt;code&gt;--random-order&lt;/code&gt; to your pytest run.&lt;/p&gt; &lt;p&gt;It &lt;a href=&#34;https://github.com/jbasko/pytest-random-order/issues/46&#34;&gt;can&#39;t yet be used&lt;/a&gt; with &lt;code&gt;pytest-xdist&lt;/code&gt; though :(.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pytest/#enforce-serial-execution-of-related-tests&#34;&gt;Enforce serial execution of related tests.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Implement a &lt;code&gt;serial&lt;/code&gt; fixture with a session-scoped file &lt;code&gt;lock&lt;/code&gt; fixture using the &lt;code&gt;filelock&lt;/code&gt; package. You can add this to your &lt;code&gt;conftest.py&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;contextlib&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;

&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;filelock&lt;/span&gt;

&lt;span class=&#34;nd&#34;&gt;@pytest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fixture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;scope&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;session&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;lock&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tmp_path_factory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;base_temp&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tmp_path_factory&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getbasetemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;lock_file&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;base_temp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;serial.lock&#39;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;yield&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filelock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FileLock&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lock_file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lock_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;contextlib&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;suppress&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;OSError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;remove&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lock_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;nd&#34;&gt;@pytest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fixture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;serial&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lock&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;lock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;acquire&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;poll_intervall&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;yield&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then inject the &lt;code&gt;serial&lt;/code&gt; fixture in any test that requires serial execution. All tests that use the serial fixture are executed serially while any tests that do not use the fixture are executed in parallel.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pytest/#using-fixtures-at-class-level&#34;&gt;Using fixtures at class level.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Sometimes test functions do not directly need access to a fixture object. For example, tests may require to operate with an empty directory as the current working directory but otherwise do not care for the concrete directory.&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nd&#34;&gt;@pytest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mark&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;usefixtures&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;cleandir&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;TestDirectoryInit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; Due to the &lt;code&gt;usefixtures&lt;/code&gt; marker, the &lt;code&gt;cleandir&lt;/code&gt; fixture will be required for the execution of each test method, just as if you specified a &lt;code&gt;cleandir&lt;/code&gt; function argument to each of them.&lt;/p&gt; &lt;p&gt;You can specify multiple fixtures like this:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nd&#34;&gt;@pytest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mark&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;usefixtures&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;cleandir&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;anotherfixture&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Improve the snippet to run some tests in serial instead of parallel.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/feedparser/#parse-a-feed-from-a-string&#34;&gt;Parse a feed from a string.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;feedparser&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rawdata&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&#34;&#34;&amp;lt;rss version=&#34;2.0&#34;&amp;gt;&lt;/span&gt;
&lt;span class=&#34;s2&#34;&gt;&amp;lt;channel&amp;gt;&lt;/span&gt;
&lt;span class=&#34;s2&#34;&gt;&amp;lt;title&amp;gt;Sample Feed&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class=&#34;s2&#34;&gt;&amp;lt;/channel&amp;gt;&lt;/span&gt;
&lt;span class=&#34;s2&#34;&gt;&amp;lt;/rss&amp;gt;&#34;&#34;&#34;&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;d&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;feedparser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rawdata&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;feed&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;][&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;title&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;sa&#34;&gt;u&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Sample Feed&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Change log level of a dependency.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;caplog&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set_level&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WARNING&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;urllib3&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pytest/#show-logging-messages-on-the-test-run&#34;&gt;Show logging messages on the test run.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Add to your &lt;code&gt;pyproject.toml&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[tool.pytest.ini_options]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log_cli&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log_cli_level&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Or run it in the command itself &lt;code&gt;pytest -o log_cli=true --log-cli-level=10 func.py&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Remember you can change the log level of the different components in case it&#39;s too verbose.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pytest/#the-tmp_path-fixture&#34;&gt;The tmp_path fixture.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can use the &lt;code&gt;tmp_path&lt;/code&gt; fixture which will provide a temporary directory unique to the test invocation, created in the base temporary directory.&lt;/p&gt; &lt;p&gt;&lt;code&gt;tmp_path&lt;/code&gt; is a &lt;code&gt;pathlib.Path&lt;/code&gt; object. Here is an example test usage:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;test_create_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tmp_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;d&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tmp_path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;sub&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mkdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;d&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;hello.txt&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;write_text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CONTENT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read_text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CONTENT&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tmp_path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iterdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()))&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pytest/#the-tmpdir-fixture&#34;&gt;Deprecate the tmpdir fixture.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Warning: Don&#39;t use &lt;code&gt;tmpdir&lt;/code&gt; use &lt;code&gt;tmp_path&lt;/code&gt; instead because &lt;code&gt;tmpdir&lt;/code&gt; uses &lt;code&gt;py&lt;/code&gt; which is unmaintained and has unpatched vulnerabilities.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Remove warning that &lt;code&gt;pytest-random-order&lt;/code&gt; can&#39;t be used with &lt;code&gt;pytest-xdist&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;The issue was fixed&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;gettext&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/python_internationalization/&#34;&gt;Gettext&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce gettext.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://docs.python.org/3/library/gettext.html&#34;&gt;Gettext&lt;/a&gt; is the defacto universal solution for &lt;a href=&#34;https://lyz-code.github.io/blue-book/python_internationalization/&#34;&gt;internationalization&lt;/a&gt; (I18N) and localization (L10N), offering a set of tools that provides a framework to help other packages produce multi-lingual messages. It gives an opinionated way of how programs should be written to support translated message strings and a directory and file naming organisation for the messages that need to be translated.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce Python Internationalization.&lt;/p&gt; &lt;p&gt;To make your code accessible to more people, you may want to support more than one language. It&#39;s not as easy as it looks as it&#39;s not enough to translate it but also it must look and feel local. The answer is internationalization.&lt;/p&gt; &lt;p&gt;Internationalization (numeronymed as i18n) can be defined as the design process that ensures a program can be adapted to various languages and regions without requiring engineering changes to the source code.&lt;/p&gt; &lt;p&gt;Common internationalization tasks include:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Facilitating compliance with Unicode.&lt;/li&gt; &lt;li&gt;Minimizing the use of concatenated strings.&lt;/li&gt; &lt;li&gt;Accommodating support for double-byte languages (e.g. Japanese) and right-to-left languages (for example, Hebrew).&lt;/li&gt; &lt;li&gt;Avoiding hard-coded text.&lt;/li&gt; &lt;li&gt;Designing for independence from cultural conventions (e. g., date and time displays), limiting language, and character sets.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Localization (l10n) refers to the adaptation of your program, once internationalized, to the local language and cultural habits. In theory it looks simple to implement. In practice though, it takes time and effort to provide the best Internationalization and Localization experience for your global audience.&lt;/p&gt; &lt;p&gt;In Python, there is a specific bundled module for that and it’s called &lt;a href=&#34;https://lyz-code.github.io/blue-book/gettext/&#34;&gt;gettext&lt;/a&gt;, which consists of a public API and a set of tools that help extract and generate message catalogs from the source code.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;python-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/&#34;&gt;Python Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#how-to-raise-a-warning&#34;&gt;How to raise a warning.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Warning messages are typically issued in situations where it is useful to alert the user of some condition in a program, where that condition (normally) doesn’t warrant raising an exception and terminating the program. For example, one might want to issue a warning when a program uses an obsolete module.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;warnings&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;warnings&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;warn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Message&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;DeprecationWarning&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To test the function with pytest you can use &lt;a href=&#34;https://docs.pytest.org/en/stable/how-to/capture-warnings.html#warns&#34;&gt;&lt;code&gt;pytest.warns&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;warnings&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pytest&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;test_warning&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pytest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;warns&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;UserWarning&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;match&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;my warning&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;warnings&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;warn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;my warning&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;UserWarning&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#parse-xml-file-with-beautifulsoup&#34;&gt;Parse XML file with beautifulsoup.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You need both &lt;code&gt;beautifulsoup4&lt;/code&gt; and &lt;code&gt;lxml&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;bs&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;BeautifulSoup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;requests&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;lxml&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-a-traceback-from-an-exception&#34;&gt;Get a traceback from an exception.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;traceback&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;traceback_str&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;join&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;traceback&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;format_tb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;__traceback__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#warning-categories&#34;&gt;Add the Warning categories.&lt;/a&gt;&lt;/p&gt; &lt;table&gt; &lt;thead&gt; &lt;tr&gt; &lt;th&gt;Class&lt;/th&gt; &lt;th&gt;Description&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Warning&lt;/td&gt; &lt;td&gt;This is the base class of all warning category classes.&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;UserWarning&lt;/td&gt; &lt;td&gt;The default category for warn().&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;DeprecationWarning&lt;/td&gt; &lt;td&gt;Warn other developers about deprecated features.&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;FutureWarning&lt;/td&gt; &lt;td&gt;Warn other end users of applications about deprecated features.&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;SyntaxWarning&lt;/td&gt; &lt;td&gt;Warn about dubious syntactic features.&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;RuntimeWarning&lt;/td&gt; &lt;td&gt;Warn about dubious runtime features.&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;PendingDeprecationWarning&lt;/td&gt; &lt;td&gt;Warn about features that will be deprecated in the future (ignored by default).&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;ImportWarning&lt;/td&gt; &lt;td&gt;Warn triggered during the process of importing a module (ignored by default).&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;UnicodeWarning&lt;/td&gt; &lt;td&gt;Warn related to Unicode.&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;BytesWarning&lt;/td&gt; &lt;td&gt;Warn related to bytes and bytearray.&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;ResourceWarning&lt;/td&gt; &lt;td&gt;Warn related to resource usage (ignored by default).&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#how-to-find-duplicates-in-a-list-in-python&#34;&gt;How to Find Duplicates in a List in Python.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;numbers&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;duplicates&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;number&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;number&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;numbers&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;numbers&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;number&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;unique_duplicates&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;duplicates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you want to count the number of occurrences of each duplicate, you can use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;collections&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Counter&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;numbers&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;counts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Counter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;numbers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;duplicates&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;counts&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;items&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To remove the duplicates use a combination of &lt;code&gt;list&lt;/code&gt; and &lt;code&gt;set&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;unique&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;numbers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#how-to-decompress-a-gz-file&#34;&gt;How to decompress a gz file.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;gzip&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;shutil&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gzip&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;file.txt.gz&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;rb&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_in&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;file.txt&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;wb&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_out&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;shutil&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;copyfileobj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_in&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_out&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#how-to-compress/decompress-a-tar-file&#34;&gt;How to compress/decompress a tar file.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;compress&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tar_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;members&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    Adds files (`members`) to a tar_file and compress it&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    &#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;tar&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tarfile&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tar_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;w:gz&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;member&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;members&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;tar&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;member&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;tar&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;decompress&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tar_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;members&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    Extracts `tar_file` and puts the `members` to `path`.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    If members is None, all members on `tar_file` will be extracted.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    &#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;tar&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tarfile&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tar_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;r:gz&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;members&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;members&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tar&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getmembers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;member&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;members&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;tar&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;extract&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;member&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;tar&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-the-attribute-of-an-attribute&#34;&gt;Get the attribute of an attribute when sorting.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To sort the list in place:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;ut&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sort&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;reverse&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To return a new list, use the &lt;code&gt;sorted()&lt;/code&gt; built-in function:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;newlist&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;sorted&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ut&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;reverse&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#how-to-extend-a-dictionary&#34;&gt;How to extend a dictionary.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;update&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#how-to-close-a-subprocess-process&#34;&gt;How to close a subprocess process.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;terminate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#define-a-property-of-a-class&#34;&gt;Define a property of a class.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you&#39;re using Python 3.9 or above you can directly use the decorators:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;nd&#34;&gt;@classmethod&lt;/span&gt;
    &lt;span class=&#34;nd&#34;&gt;@property&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;__doc__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;cls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;A doc for &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;cls&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;!r}&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you&#39;re not, the solutions are not that good.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#fix-sim113-use-enumerate&#34;&gt;Fix SIM113 Use enumerate.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use &lt;code&gt;enumerate&lt;/code&gt; to get a running number over an iterable.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;idx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;el&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;iterable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;idx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;idx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;el&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;enumerate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iterable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#parse-an-rfc2822-date&#34;&gt;Parse an RFC2822 date.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Interesting to test the accepted format of &lt;a href=&#34;https://www.rssboard.org/rss-validator/docs/error/InvalidRFC2822Date.html&#34;&gt;RSS dates&lt;/a&gt;.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;email.utils&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parsedate_to_datetime&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datestr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;Sun, 09 Mar 1997 13:45:00 -0500&#39;&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parsedate_to_datetime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;datestr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1997&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;9&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;13&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;45&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tzinfo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timezone&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timedelta&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;68400&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#convert-a-datetime-to-rfc2822&#34;&gt;Convert a datetime to RFC2822.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Interesting as it&#39;s the accepted format of &lt;a href=&#34;https://www.rssboard.org/rss-validator/docs/error/InvalidRFC2822Date.html&#34;&gt;RSS dates&lt;/a&gt;.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;datetime&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;email&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;utils&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nowdt&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;utils&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;format_datetime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nowdt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;&#39;Tue, 10 Feb 2020 10:06:53 -0000&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#encode-url&#34;&gt;Encode url.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;urllib.parse&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pydantic&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;AnyHttpUrl&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;_normalize_url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;AnyHttpUrl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Encode url to make it compatible with AnyHttpUrl.&#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;typing&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cast&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;AnyHttpUrl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;urllib&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parse&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;quote&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;:/&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The &lt;code&gt;:/&lt;/code&gt; is needed when you try to parse urls that have the protocol, otherwise &lt;code&gt;https://www.&lt;/code&gt; gets transformed into &lt;code&gt;https%3A//www.&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#initialize-a-dataclass-with-kwargs&#34;&gt;Initialize a dataclass with kwargs.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you care about accessing attributes by name, or if you can&#39;t distinguish between known and unknown arguments during initialisation, then your last resort without rewriting &lt;code&gt;__init__&lt;/code&gt; (which pretty much defeats the purpose of using dataclasses in the first place) is writing a &lt;code&gt;@classmethod&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;dataclasses&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dataclass&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;inspect&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;signature&lt;/span&gt;

&lt;span class=&#34;nd&#34;&gt;@dataclass&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Container&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;user_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;

    &lt;span class=&#34;nd&#34;&gt;@classmethod&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;from_kwargs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;cls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kwargs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;# fetch the constructor&#39;s signature&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;cls_fields&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;field&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;field&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;signature&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;cls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parameters&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

        &lt;span class=&#34;c1&#34;&gt;# split the kwargs into native ones and new ones&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;native_args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new_args&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{},&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;kwargs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;items&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cls_fields&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;native_args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;new_args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;

        &lt;span class=&#34;c1&#34;&gt;# use the native ones to create the class ...&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;ret&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;cls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;native_args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

        &lt;span class=&#34;c1&#34;&gt;# ... and add the new ones by hand&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new_value&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new_args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;items&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
            &lt;span class=&#34;nb&#34;&gt;setattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ret&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new_value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Usage:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;params&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;user_id&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;body&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;foo&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;bar&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;baz&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;amount&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;Container&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# still doesn&#39;t work, raises a TypeError&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;c&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Container&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;from_kwargs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# prints: &#39;baz&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#replace-a-substring-of-a-string&#34;&gt;Replace a substring of a string.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;txt&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;I like bananas&#34;&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;txt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;replace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;bananas&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;apples&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#create-random-number&#34;&gt;Create random number.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;random&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;random&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;randint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#check-if-local-port-is-available-or-in-use&#34;&gt;Check if local port is available or in use.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Create a temporary socket and then try to bind to the port to see if it&#39;s available. Close the socket after validating that the port is available.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;port_in_use&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Test if a local port is used.&#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;sock&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;socket&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;socket&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;socket&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AF_INET&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;socket&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SOCK_STREAM&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;suppress&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;OSError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;sock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;0.0.0.0&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;sock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#fix-r1728:-consider-using-a-generator&#34;&gt;Fix R1728: Consider using a generator.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Removing &lt;code&gt;[]&lt;/code&gt; inside calls that can use containers or generators should be considered for performance reasons since a generator will have an upfront cost to pay. The performance will be better if you are working with long lists or sets.&lt;/p&gt; &lt;p&gt;Problematic code:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))])&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# [consider-using-generator]&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;tuple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))])&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# [consider-using-generator]&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;sum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))])&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# [consider-using-generator]&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))])&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# [consider-using-generator]&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;min&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))])&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# [consider-using-generator]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Correct code:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;tuple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;sum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;min&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#fix-w1510:-using-subprocess.run-without-explicitly-set-check-is-not-recommended&#34;&gt;Fix W1510: Using subprocess.run without explicitly set check is not recommended.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The &lt;code&gt;run&lt;/code&gt; call in the example will succeed whether the command is successful or not. This is a problem because we silently ignore errors.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;subprocess&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;example&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;proc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;ls&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;proc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stdout&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;When we pass &lt;code&gt;check=True&lt;/code&gt;, the behavior changes towards raising an exception when the return code of the command is non-zero.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#convert-bytes-to-string&#34;&gt;Convert bytes to string.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;byte_var&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;decode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;utf-8&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#use-pipes-with-subprocess&#34;&gt;Use pipes with subprocess.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To use pipes with subprocess you need to use the flag &lt;code&gt;check=True&lt;/code&gt; which is &lt;a href=&#34;https://github.com/duo-labs/dlint/blob/master/docs/linters/DUO116.md&#34;&gt;a bad idea&lt;/a&gt;. Instead you should use two processes and link them together in python:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;ps&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Popen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;ps&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;-A&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stdout&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PIPE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;output&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;check_output&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;grep&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;process_name&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stdin&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ps&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stdout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;ps&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wait&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#pass-input-to-the-stdin-of-a-subprocess&#34;&gt;Pass input to the stdin of a subprocess.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;subprocess&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;myapp&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;data_to_write&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#copy-and-paste-from-clipboard&#34;&gt;Copy and paste from clipboard.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can use &lt;a href=&#34;https://www.delftstack.com/howto/python/python-copy-to-clipboard/&#34;&gt;many libraries&lt;/a&gt; to do it, but if you don&#39;t want to add any other dependencies you can use &lt;code&gt;subprocess run&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;To copy from the &lt;code&gt;selection&lt;/code&gt; clipboard, assuming you&#39;ve got &lt;code&gt;xclip&lt;/code&gt; installed, you could do:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;xclip&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;-selection&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;clipboard&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;-i&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;text to be copied&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;check&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To paste it:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;check_output&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;xclip&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;-o&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;-selection&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;clipboard&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;decode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;utf-8&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Good luck testing that in the CI xD&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-an-instance-of-an-enum-by-value&#34;&gt;Get an instance of an Enum by value.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you want to initialize a pydantic model with an &lt;code&gt;Enum&lt;/code&gt; but all you have is the value of the &lt;code&gt;Enum&lt;/code&gt; then you need to create a method to get the correct Enum. Otherwise &lt;code&gt;mypy&lt;/code&gt; will complain that the type of the assignation is &lt;code&gt;str&lt;/code&gt; and not &lt;code&gt;Enum&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;So if the model is the next one:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;ServiceStatus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BaseModel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Model the docker status of a service.&#34;&#34;&#34;&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;environment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Environment&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can&#39;t do &lt;code&gt;ServiceStatus(name=&#39;test&#39;, environment=&#39;production&#39;)&lt;/code&gt;. you need to add the &lt;code&gt;get_by_value&lt;/code&gt; method to the &lt;code&gt;Enum&lt;/code&gt; class:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Environment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Enum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Set the possible environments.&#34;&#34;&#34;&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;STAGING&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;staging&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;PRODUCTION&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;production&#34;&lt;/span&gt;

    &lt;span class=&#34;nd&#34;&gt;@classmethod&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;get_by_value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;cls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Enum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Return the Enum element that meets a value&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;member&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;member&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;cls&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;member&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;][&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Now you can do:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;ServiceStatus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;test&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;environment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Environment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_by_value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;production&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#print-datetime-with-a-defined-format&#34;&gt;Print datetime with a defined format.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;now&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;today&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;strftime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;We are the &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%d&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;, %b %Y&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where the datetime format is a string built from &lt;a href=&#34;#parse-a-datetime-from-a-string&#34;&gt;these directives&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#print-string-with-asciiart&#34;&gt;Print string with asciiart.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pyfiglet
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pyfiglet&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;figlet_format&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;figlet_format&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;09 : 30&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you want to change the default width of 80 caracteres use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pyfiglet&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Figlet&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Figlet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;font&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;standard&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;renderText&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;aaaaaaaaaaaaaaaaa&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#print-specific-time-format&#34;&gt;Print specific time format.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;strftime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;%Y-%m-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%d&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;T%H:%M:%S&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Code Meaning Example %a Weekday as locale’s abbreviated name. Mon %A Weekday as locale’s full name. Monday %w Weekday as a decimal number, where 0 is Sunday and 6 is Saturday. 1 %d Day of the month as a zero-padded decimal number. 30 %-d Day of the month as a decimal number. (Platform specific) 30 %b Month as locale’s abbreviated name. Sep %B Month as locale’s full name. September %m Month as a zero-padded decimal number. 09 %-m Month as a decimal number. (Platform specific) 9 %y Year without century as a zero-padded decimal number. 13 %Y Year with century as a decimal number. 2013 %H Hour (24-hour clock) as a zero-padded decimal number. 07 %-H Hour (24-hour clock) as a decimal number. (Platform specific) 7 %I Hour (12-hour clock) as a zero-padded decimal number. 07 %-I Hour (12-hour clock) as a decimal number. (Platform specific) 7 %p Locale’s equivalent of either AM or PM. AM %M Minute as a zero-padded decimal number. 06 %-M Minute as a decimal number. (Platform specific) 6 %S Second as a zero-padded decimal number. 05 %-S Second as a decimal number. (Platform specific) 5 %f Microsecond as a decimal number, zero-padded on the left. 000000 %z UTC offset in the form +HHMM or -HHMM (empty string if the object is naive). %Z Time zone name (empty string if the object is naive). %j Day of the year as a zero-padded decimal number. 273 %-j Day of the year as a decimal number. (Platform specific) 273 %U Week number of the year (Sunday as the first day of the week) as a zero padded decimal number. All days in a new year preceding the first Sunday are considered to be in week 0. 39 %W Week number of the year (Monday as the first day of the week) as a decimal number. All days in a new year preceding the first Monday are considered to be in week 0. %c Locale’s appropriate date and time representation. Mon Sep 30 07:06:05 2013 %x Locale’s appropriate date representation. 09/30/13 %X Locale’s appropriate time representation. 07:06:05 %% A literal &#39;%&#39; character. %&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Deprecate tmpdir in favour of tmp_path.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#pad-integer-with-zeros&#34;&gt;Pad integer with zeros.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;length&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;length = &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;length&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;03&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;length&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;001&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#pathlib-make-parent-directories-if-they-don&#39;t-exist&#34;&gt;Pathlib make parent directories if they don&#39;t exist.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;pathlib&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;/tmp/sub1/sub2&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mkdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exist_ok&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;From the &lt;a href=&#34;https://docs.python.org/3/library/pathlib.html#pathlib.Path.mkdir&#34;&gt;docs&lt;/a&gt;:&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;If &lt;code&gt;parents&lt;/code&gt; is &lt;code&gt;true&lt;/code&gt;, any missing parents of this path are created as needed; they are created with the default permissions without taking mode into account (mimicking the POSIX &lt;code&gt;mkdir -p&lt;/code&gt; command).&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;If &lt;code&gt;parents&lt;/code&gt; is &lt;code&gt;false&lt;/code&gt; (the default), a missing parent raises &lt;code&gt;FileNotFoundError&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;If &lt;code&gt;exist_ok&lt;/code&gt; is &lt;code&gt;false&lt;/code&gt; (the default), &lt;code&gt;FileExistsError&lt;/code&gt; is raised if the target directory already exists.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;If &lt;code&gt;exist_ok&lt;/code&gt; is &lt;code&gt;true&lt;/code&gt;, &lt;code&gt;FileExistsError&lt;/code&gt; exceptions will be ignored (same behavior as the POSIX &lt;code&gt;mkdir -p&lt;/code&gt; command), but only if the last path component is not an existing non-directory file.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#pathlib-touch-a-file&#34;&gt;Pathlib touch a file.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Create a file at this given path.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;pathlib&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;/tmp/file.txt&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;touch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exist_ok&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If the file already exists, the function succeeds if &lt;code&gt;exist_ok&lt;/code&gt; is &lt;code&gt;true&lt;/code&gt; (and its modification time is updated to the current time), otherwise &lt;code&gt;FileExistsError&lt;/code&gt; is raised.&lt;/p&gt; &lt;p&gt;If the parent directory doesn&#39;t exist you need to create it first.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;global_conf_path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;xdg_home&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;autoimport&#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;config.toml&#34;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;global_conf_path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parent&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mkdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;global_conf_path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;touch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exist_ok&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#pad-a-string-with-spaces&#34;&gt;Pad a string with spaces.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;John&#39;&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ljust&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;&#39;John           &#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-hostname-of-the-machine&#34;&gt;Get hostname of the machine.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Any of the next three options:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;

&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;platform&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;socket&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;socket&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gethostname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-common-elements-of-two-lists&#34;&gt;Get common elements of two lists.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;a&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;b&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;c&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;d&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;b&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;b&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#recursively-find-files&#34;&gt;Recursively find files.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pathlib&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;src&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rglob&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;*.c&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#using-the-logging-module&#34;&gt;Print an exception using the logging module.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Logging an exception can be done with the module-level function &lt;code&gt;logging.exception()&lt;/code&gt; like so:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;logging&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;BaseException&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exception&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;An exception was thrown!&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ERROR:root:An exception was thrown!
Traceback (most recent call last):
File &#34;.../Desktop/test.py&#34;, line 4, in &amp;lt;module&amp;gt;
    1/0
ZeroDivisionError: division by zero
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Notes&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;The function &lt;code&gt;logging.exception()&lt;/code&gt; should only be called from an exception handler.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;The logging module should not be used inside a logging handler to avoid a &lt;code&gt;RecursionError&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;It&#39;s also possible to log the exception with another log level but still show the exception details by using the keyword argument &lt;code&gt;exc_info=True&lt;/code&gt;, like so:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;critical&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;An exception was thrown!&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exc_info&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;An exception was thrown!&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exc_info&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;warning&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;An exception was thrown!&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exc_info&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;An exception was thrown!&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exc_info&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;debug&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;An exception was thrown!&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exc_info&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;An exception was thrown!&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exc_info&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#with-the-traceback-module&#34;&gt;Print an exception with the traceback module.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The &lt;code&gt;traceback&lt;/code&gt; module provides methods for formatting and printing exceptions and their tracebacks, e.g. this would print exception like the default handler does:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;traceback&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;Exception&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;traceback&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;print_exc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;Traceback&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;most&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;recent&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;call&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;last&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;File&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;C:\scripts\divide_by_zero.py&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;line&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;ne&#34;&gt;ZeroDivisionError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;division&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;by&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;zero&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;ics&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/ics/&#34;&gt;ICS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce ICS.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://icspy.readthedocs.io/en/stable/index.html&#34;&gt;ics&lt;/a&gt; is a pythonic iCalendar library. Its goals are to read and write ics data in a developer-friendly way.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;maison&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/maison/&#34;&gt;Maison&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Maison.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/dbatten5/maison&#34;&gt;Maison&lt;/a&gt; is a Python library to read configuration settings from configuration files using &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pydantic/&#34;&gt;&lt;code&gt;pydantic&lt;/code&gt;&lt;/a&gt; behind the scenes.&lt;/p&gt; &lt;p&gt;It&#39;s useful to parse TOML config files.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pydantic&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pydantic/&#34;&gt;Pydantic&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Use mypy pydantic&#39;s plugin.&lt;/p&gt; &lt;p&gt;If you use &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/mypy/&#34;&gt;mypy&lt;/a&gt; I highly recommend you to &lt;a href=&#34;https://pydantic-docs.helpmanual.io/mypy_plugin/#configuring-the-plugin&#34;&gt;activate the pydantic plugin&lt;/a&gt; by adding to your &lt;code&gt;pyproject.toml&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[tool.mypy]&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;plugins&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;pydantic.mypy&#34;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[tool.pydantic-mypy]&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;init_forbid_extra&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;init_typed&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;warn_required_dynamic_aliases&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;warn_untyped_fields&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pydantic/#ignore-a-field-when-representing-an-object&#34;&gt;Ignore a field when representing an object.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use &lt;code&gt;repr=False&lt;/code&gt;. This is useful for properties that don&#39;t return a value quickly, for example if you save an &lt;code&gt;sh&lt;/code&gt; background process.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Temp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BaseModel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;typing&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Any&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;boo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;typing&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Any&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Field&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;repr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;elasticsearch&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/elasticsearch/&#34;&gt;Elasticsearch&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/elasticsearch/#delete-snapshot-repository&#34;&gt;Delete snapshot repository.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-XDELETE&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;url&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;/_snapshot/&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;backup_path&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/elasticsearch/#searching-documents&#34;&gt;Searching documents.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;We use HTTP requests to talk to ElasticSearch. A HTTP request is made up of several components such as the URL to make the request to, HTTP verbs (GET, POST etc) and headers. In order to succinctly and consistently describe HTTP requests the ElasticSearch documentation uses cURL command line syntax. This is also the standard practice to describe requests made to ElasticSearch within the user community.&lt;/p&gt; &lt;p&gt;An example HTTP request using CURL syntax looks like this:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-XPOST&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;https://localhost:9200/_search&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;s1&#34;&gt;&#39; { &#34;query&#34;: { &#34;match_all&#34;: {} }&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;}&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/elasticsearch/#get-documents-that-match-a-string&#34;&gt;Get documents that match a string.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;-H&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Content-Type: application/json&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;-XPOST&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;https://localhost:9200/_search&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;-d&lt;span class=&#34;s1&#34;&gt;&#39; { &#34;query&#34;: { &#34;query_string&#34;: {&#34;query&#34;: &#34;test company&#34;} }}&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce python elasticsearch library.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://elasticsearch-py.readthedocs.io/en/latest/&#34;&gt;Python elasticsearch&lt;/a&gt; is the Official low-level client for Elasticsearch. Its goal is to provide common ground for all Elasticsearch-related code in Python; because of this it tries to be opinion-free and very extendable.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://elasticsearch-py.readthedocs.io/en/latest/#installation&#34;&gt;Installation&lt;/a&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;elasticsearch
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Usage:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;elasticsearch&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Elasticsearch&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;client&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Elasticsearch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;http://localhost:9200&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;indices&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;*&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;resp&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;search&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;test-index&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;query&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;match_all&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}})&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;documents&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;resp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;hits&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;][&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;hits&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;doc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;partial_document&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;value&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;resp&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;update&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INDEX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;doc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;doc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;python-mysql&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/sql/sql/&#34;&gt;Python Mysql&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/sql/sql/#list-all-tables&#34;&gt;List all tables using different databases.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Mysql:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;show&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tables&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Postgresql:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;err&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Sqlite:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tables&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pythonping&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/pythonping/&#34;&gt;pythonping&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce pythonping.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/alessandromaggio/pythonping&#34;&gt;pythonping&lt;/a&gt; is simple way to ping in Python. With it, you can send ICMP Probes to remote devices like you would do from the terminal.&lt;/p&gt; &lt;p&gt;Warning: Since using &lt;code&gt;pythonping&lt;/code&gt; requires root permissions or granting &lt;code&gt;cap_net_raw&lt;/code&gt; capability to the python interpreter, try to measure the latency to a server by other means such as using &lt;code&gt;requests&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;python-vlc&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/python_vlc/&#34;&gt;Python VLC&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce python&#39;s vlc library.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://wiki.videolan.org/Python_bindings/&#34;&gt;Python VLC&lt;/a&gt; is a library to control &lt;code&gt;vlc&lt;/code&gt; from python.&lt;/p&gt; &lt;p&gt;There is not usable online documentation, you&#39;ll have to go through the &lt;code&gt;help(&amp;lt;component&amp;gt;)&lt;/code&gt; inside the python console.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;questionary&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/questionary/&#34;&gt;questionary&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/questionary/#exit-when-using-control-+-c&#34;&gt;Exit when using control + c.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you want the question to exit when it receives a &lt;code&gt;KeyboardInterrupt&lt;/code&gt; event, use &lt;code&gt;unsafe_ask&lt;/code&gt; instead of &lt;code&gt;ask&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;rich&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/rich/&#34;&gt;rich&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/rich/#live-display-text&#34;&gt;Live display text.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;time&lt;/span&gt;

&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;rich.live&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Live&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Live&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Test&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;live&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;row&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;live&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;update&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Test &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;row&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sleep&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you don&#39;t want the text to have the default colors, you can embed it all in a &lt;code&gt;Text&lt;/code&gt; object.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;selenium&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/selenium/&#34;&gt;Selenium&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/selenium/#click-on-element&#34;&gt;Click on element.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Once you&#39;ve opened the page you want to interact with &lt;code&gt;driver.get()&lt;/code&gt;, you need to get the Xpath of the element to click on. You can do that by using your browser inspector, to select the element, and once on the code if you right click there is a &#34;Copy XPath&#34;&lt;/p&gt; &lt;p&gt;Once that is done you should have something like this when you paste it down.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;//*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@id&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;”&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;react&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;root&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;”&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;section&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;article&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;div&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;div&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Similarly it is the same process for the input fields for username, password, and login button.&lt;/p&gt; &lt;p&gt;We can go ahead and do that on the current page. We can store these xpaths as strings in our code to make it readable.&lt;/p&gt; &lt;p&gt;We should have three xpaths from this page and one from the initial login.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;first_login&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;//*[@id=”react-root”]/section/main/article/div[2]/div[2]/p/a&#39;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;username_input&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;//*[@id=&#34;react-root&#34;]/section/main/div/article/div/div[1]/div/form/div[2]/div/label/input&#39;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;password_input&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;//*[@id=&#34;react-root&#34;]/section/main/div/article/div/div[1]/div/form/div[3]/div/label/input&#39;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;login_submit&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;//*[@id=&#34;react-root&#34;]/section/main/div/article/div/div[1]/div/form/div[4]/button/div&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Now that we have the xpaths defined we can now tell Selenium webdriver to click and send some keys over for the input fields.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;selenium.webdriver.common.by&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;By&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;driver&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;find_element&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;By&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;XPATH&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;first_login&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;click&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;driver&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;find_element&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;By&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;XPATH&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;username_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;send_keys&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;username&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;driver&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;find_element&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;By&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;XPATH&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;password_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;send_keys&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;password&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;driver&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;find_element&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;By&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;XPATH&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;login_submit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;click&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/selenium/#bypass-selenium-detectors&#34;&gt;Bypass Selenium detectors.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Sometimes web servers react differently if they notice that you&#39;re using selenium. Browsers can be detected through different ways and some commonly used mechanisms are as follows:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Implementing captcha / recaptcha to detect the automatic bots.&lt;/li&gt; &lt;li&gt;Non-human behaviour (browsing too fast, not scrolling to the visible elements, ...)&lt;/li&gt; &lt;li&gt;Using an IP that&#39;s flagged as suspicious (VPN, VPS, Tor...)&lt;/li&gt; &lt;li&gt;Detecting the term HeadlessChrome within headless Chrome UserAgent&lt;/li&gt; &lt;li&gt;Using Bot Management service from &lt;a href=&#34;http://www.distilnetworks.com/&#34;&gt;Distil Networks&lt;/a&gt;, &lt;a href=&#34;https://www.akamai.com/us/en/products/security/bot-manager.jsp&#34;&gt;Akamai&lt;/a&gt;, &lt;a href=&#34;https://datadome.co/product/&#34;&gt;Datadome&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;They do it through different mechanisms:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/selenium/#use-undetected-chromedriver&#34;&gt;Use undetected-chromedriver&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/selenium/#use-selenium-stealth&#34;&gt;Use Selenium stealth&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/selenium/#rotate-the-user-agent&#34;&gt;Rotate the user agent&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/selenium/#changing-browser-properties&#34;&gt;Changing browser properties&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/selenium/#predefined-javascript-variables&#34;&gt;Predefined Javascript variables&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/selenium/#dont-use-selenium&#34;&gt;Don&#39;t use selenium&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;If you&#39;ve already been detected, you might get blocked for a plethora of other reasons even after using these methods. So you may have to try accessing the site that was detecting you using a VPN, different user-agent, etc.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/selenium/#open-a-url&#34;&gt;Basic Selenium commands.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Open a URL:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;driver&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;https://duckduckgo.com/&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Get page source:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;driver&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;page_source&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Get current url:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;driver&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current_url&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/selenium/#disable-loading-of-images&#34;&gt;Disable loading of images.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can pass &lt;code&gt;options&lt;/code&gt; to the initialization of the chromedriver to tweak how does the browser behave. To get a list of the actual &lt;code&gt;prefs&lt;/code&gt; you can go to &lt;code&gt;chrome://prefs-internals&lt;/code&gt;, there you can get the code you need to tweak.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;options&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ChromeOptions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;options&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_experimental_option&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;prefs&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;profile.default_content_setting_values.images&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;sqlite3&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/sqlite3/&#34;&gt;sqlite3&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/sqlite3/#get-a-list-of-the-tables&#34;&gt;Get a list of the tables.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;sql_query&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&#34;&#34;SELECT name FROM sqlite_master&lt;/span&gt;
&lt;span class=&#34;s2&#34;&gt;  WHERE type=&#39;table&#39;;&#34;&#34;&#34;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;cursor&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sqliteConnection&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cursor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;cursor&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;execute&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sql_query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cursor&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fetchall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;sh&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/python_sh/&#34;&gt;sh&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/python_sh/#avoid-exception-logging-when-killing-a-background-process&#34;&gt;Avoid exception logging when killing a background process.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;In order to catch this exception execute your process with &lt;code&gt;_bg_exec=False&lt;/code&gt; and execute &lt;code&gt;p.wait()&lt;/code&gt; if you want to handle the exception. Otherwise don&#39;t use the &lt;code&gt;p.wait()&lt;/code&gt;.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sh&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sleep&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_bg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_bg_exc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kill&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wait&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sh&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SignalException_SIGKILL&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;foo&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;foo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;typer&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/typer/&#34;&gt;Typer&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Typer.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://typer.tiangolo.com/&#34;&gt;Typer&lt;/a&gt; is a library for building CLI applications that users will love using and developers will love creating. Based on Python 3.6+ type hints.&lt;/p&gt; &lt;p&gt;The key features are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;em&gt;Intuitive to write&lt;/em&gt;: Great editor support. Completion everywhere. Less time debugging. Designed to be easy to use and learn. Less time reading docs.&lt;/li&gt; &lt;li&gt;&lt;em&gt;Easy to use&lt;/em&gt;: It&#39;s easy to use for the final users. Automatic help, and automatic completion for all shells.&lt;/li&gt; &lt;li&gt;&lt;em&gt;Short&lt;/em&gt;: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.&lt;/li&gt; &lt;li&gt;&lt;em&gt;Start simple&lt;/em&gt;: The simplest example adds only 2 lines of code to your app: 1 import, 1 function call.&lt;/li&gt; &lt;li&gt;&lt;em&gt;Grow large&lt;/em&gt;: Grow in complexity as much as you want, create arbitrarily complex trees of commands and groups of subcommands, with options and arguments.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/typer/#get-the-command-line-application-directory&#34;&gt;Get the command line application directory.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can get the application directory where you can, for example, save configuration files with &lt;code&gt;typer.get_app_dir()&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pathlib&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;

&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;typer&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;APP_NAME&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;my-super-cli-app&#34;&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Define the main command line interface.&#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;app_dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;typer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_app_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;APP_NAME&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;config_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;app_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;config.json&#34;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;config_path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Config file doesn&#39;t exist yet&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;__main__&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;typer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;It will give you a directory for storing configurations appropriate for your CLI program for the current user in each operating system.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/typer/#exiting-with-an-error-code&#34;&gt;Exiting with an error code.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;typer.Exit()&lt;/code&gt; takes an optional code parameter. By default, code is &lt;code&gt;0&lt;/code&gt;, meaning there was no error.&lt;/p&gt; &lt;p&gt;You can pass a code with a number other than &lt;code&gt;0&lt;/code&gt; to tell the terminal that there was an error in the execution of the program:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;typer&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;username&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;username&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;root&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;The root user is reserved&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;typer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Exit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;code&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;New user created: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;username&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;__main__&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;typer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/typer/#create-a---version-command-&#34;&gt;Create a &lt;code&gt;--version&lt;/code&gt; command.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You could use a callback to implement a &lt;code&gt;--version&lt;/code&gt; CLI option.&lt;/p&gt; &lt;p&gt;It would show the version of your CLI program and then it would terminate it. Even before any other CLI parameter is processed.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;typing&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Optional&lt;/span&gt;

&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;typer&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;__version__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;0.1.0&#34;&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;version_callback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Print the version of the program.&#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Awesome CLI Version: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;__version__&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;typer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Exit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Optional&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;typer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Option&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;--version&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;callback&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;version_callback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;is_eager&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;__main__&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;typer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/typer/#testing&#34;&gt;Testing.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Testing is similar to &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/click/#testing-click-applications&#34;&gt;&lt;code&gt;click&lt;/code&gt; testing&lt;/a&gt;, but you import the &lt;code&gt;CliRunner&lt;/code&gt; directly from &lt;code&gt;typer&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;typer.testing&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CliRunner&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;generic-coding-practices&#34;&gt;Generic Coding Practices&lt;/h3&gt; &lt;h4 id=&#34;use-warnings-to-evolve-your-code&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/use_warnings/&#34;&gt;Use warnings to evolve your code&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Using warnings to evolve your package.&lt;/p&gt; &lt;p&gt;Regardless of the &lt;a href=&#34;https://lyz-code.github.io/blue-book/versioning/&#34;&gt;versioning system&lt;/a&gt; you&#39;re using, once you reach your first stable version, the commitment to your end users must be that you give them time to adapt to the changes in your program. So whenever you want to introduce a breaking change release it under a new interface, and in parallel, start emitting &lt;code&gt;DeprecationWarning&lt;/code&gt; or &lt;code&gt;UserWarning&lt;/code&gt; messages whenever someone invokes the old one. Maintain this state for a defined period (for example six months), and communicate explicitly in the warning message the timeline for when users have to migrate.&lt;/p&gt; &lt;p&gt;This gives everyone time to move to the new interface without breaking their system, and then the library may remove the change and get rid of the old design chains forever. As an added benefit, only people using the old interface will ever see the warning, as opposed to affecting everyone (as seen with the semantic versioning major version bump).&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Change signature of method if you can.&lt;/p&gt; &lt;p&gt;You can take the chance of the deprecation to change the signature of the function, so that if the user is using the old argument, it uses the old behaviour and gets the warning, and if it&#39;s using the new argument, it uses the new. The advantage of changing the signature is that you don&#39;t need to do another deprecation for the temporal argument flag.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/use_warnings/#use-environmental-variables&#34;&gt;Use environmental variables to evolve your packages.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;A cleaner way to handle the package evolve is with environmental variables, that way you don&#39;t need to change the signature of the function twice. I&#39;ve learned this from &lt;a href=&#34;https://github.com/boto/botocore/issues/2705&#34;&gt;boto&lt;/a&gt; where they informed their users this way:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;If you wish to test the new feature we have created a new environment variable &lt;code&gt;BOTO_DISABLE_COMMONNAME&lt;/code&gt;. Setting this to &lt;code&gt;true&lt;/code&gt; will suppress the warning and use the new functionality.&lt;/li&gt; &lt;li&gt;If you are concerned about this change causing disruptions, you can pin your version of &lt;code&gt;botocore&lt;/code&gt; to &lt;code&gt;&amp;lt;1.28.0&lt;/code&gt; until you are ready to migrate.&lt;/li&gt; &lt;li&gt; &lt;p&gt;If you are only concerned about silencing the warning in your logs, use &lt;code&gt;warnings.filterwarnings&lt;/code&gt; when instantiating a new service client.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;warnings&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;warnings&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;filterwarnings&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;ignore&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;category&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;FutureWarning&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;botocore.client&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;abstract-syntax-trees&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/abstract_syntax_trees/&#34;&gt;Abstract Syntax Trees&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce abstract syntax trees.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Abstract_syntax_tree&#34;&gt;Abstract syntax trees&lt;/a&gt; (AST) is a tree representation of the abstract syntactic structure of text (often source code) written in a formal language. Each node of the tree denotes a construct occurring in the text.&lt;/p&gt; &lt;p&gt;The syntax is &#34;abstract&#34; in the sense that it does not represent every detail appearing in the real syntax, but rather just the structural or content-related details. For instance, grouping parentheses are implicit in the tree structure, so these do not have to be represented as separate nodes. Likewise, a syntactic construct like an if-condition-then statement may be denoted by means of a single node with three branches.&lt;/p&gt; &lt;p&gt;This distinguishes abstract syntax trees from concrete syntax trees, traditionally designated parse trees. Parse trees are typically built by a parser during the source code translation and compiling process. Once built, additional information is added to the AST by means of subsequent processing, e.g., contextual analysis.&lt;/p&gt; &lt;p&gt;Abstract syntax trees are also used in program analysis and program transformation systems.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/pyparsing/pyparsing/&#34;&gt;&lt;code&gt;pyparsing&lt;/code&gt;&lt;/a&gt; looks to be a good candidate to &lt;a href=&#34;https://stackoverflow.com/questions/1721553/how-to-construct-an-abstract-syntax-tree&#34;&gt;construct an AST&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;frontend-development&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/frontend_development/&#34;&gt;Frontend Development&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/frontend_development/#newbie-tips&#34;&gt;Newbie tips.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I&#39;ve recently started learning how to make web frontends, I feel completely lost xD. I don&#39;t know even how to search well what I need, it&#39;s like going back to programming 101. So I&#39;m seeing things that you don&#39;t see when you already are proficient in a language, so here are some tips.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/frontend_development/#dont-resize-your-browser-window&#34;&gt;Don&#39;t resize your browser window&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/frontend_development/#your-frontend-probably-doesnt-talk-to-your-backend&#34;&gt;Your frontend probably doesn&#39;t talk to your backend&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/frontend_development/#write-testable-code&#34;&gt;Write testable code&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/frontend_development/#ux-design&#34;&gt;UX design.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The most popular tool out there is &lt;code&gt;Figma&lt;/code&gt; but it&#39;s closed sourced, the alternative (quite popular in github) is &lt;a href=&#34;https://penpot.app/&#34;&gt;&lt;code&gt;penpot&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;git&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/git/&#34;&gt;Git&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce git and how to learn it.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Git&#34;&gt;Git&lt;/a&gt; is a software for tracking changes in any set of files, usually used for coordinating work among programmers collaboratively developing source code during software development. Its goals include speed, data integrity, and support for distributed, non-linear workflows (thousands of parallel branches running on different systems).&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: &lt;a href=&#34;https://lyz-code.github.io/blue-book/git/#change&#39;s-controversy&#34;&gt;Master to main branch change&#39;s controversy.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The change is not free of controversy, for example in the &lt;a href=&#34;https://github.com/pdm-project/pdm/pull/1064&#34;&gt;PDM project&lt;/a&gt; some people are not sure that it&#39;s needed for many reasons. Let&#39;s see each of them:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;em&gt;The reason people are implementing the change is because other people are doing it&lt;/em&gt;: After a quick search I found that the first one to do the change was &lt;a href=&#34;https://sfconservancy.org/news/2020/jun/23/gitbranchname/&#34;&gt;the software freedom conservancy with the Git project&lt;/a&gt;. You can also see &lt;a href=&#34;https://github.com/python/cpython/issues/78786&#34;&gt;Python&lt;/a&gt;, &lt;a href=&#34;https://github.com/django/django/pull/2692&#34;&gt;Django&lt;/a&gt;, &lt;a href=&#34;https://github.com/redis/redis/issues/3185&#34;&gt;Redis&lt;/a&gt;, &lt;a href=&#34;https://www.drupal.org/node/2275877&#34;&gt;Drupal&lt;/a&gt;, &lt;a href=&#34;https://issues.apache.org/jira/browse/COUCHDB-2248&#34;&gt;CouchDB&lt;/a&gt; and &lt;a href=&#34;https://www.theserverside.com/feature/Why-GitHub-renamed-its-master-branch-to-main&#34;&gt;Github&lt;/a&gt;&#39;s statements.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;As we&#39;re not part of the deciding organisms of the collectives doing the changes, all we can use are their statements and discussions to guess what are the reasons behind their support of the change. Despite that some of them do use the argument that other communities do support the change to emphasize the need of the change, all of them mention that the main reason is that the term is offensive to some people.&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;&lt;em&gt;I don&#39;t see an issue using the term master&lt;/em&gt;: If you relate to this statement it can be because you&#39;re not part of the communities that suffer the oppression tied to the term, and that makes you blind to the issue. It&#39;s a lesson I learned on my own skin throughout the years. There are thousand of situations, gestures, double meaning words and sentences that went unnoticed by me until I started discussing it with the people that are suffering them (women, racialized people, LGTBQI+, ...). Throughout my experience I&#39;ve seen that the more privileged you are, the blinder you become. You can read more on privileged blindness &lt;a href=&#34;https://iveybusinessjournal.com/fighting-privilege-blindness/&#34;&gt;here&lt;/a&gt;, &lt;a href=&#34;https://dojustice.crcna.org/article/becoming-aware-my-privilege&#34;&gt;here&lt;/a&gt; or &lt;a href=&#34;https://www.mindful.org/the-research-on-white-privilege-blindness/&#34;&gt;here&lt;/a&gt; (I&#39;ve skimmed through the articles, and are the first articles I&#39;ve found, there are probably better references).&lt;/p&gt; &lt;p&gt;I&#39;m not saying that privileged people are not aware of the issues or that they can even raise them. We can do so and more we read, discuss and train ourselves, the better we&#39;ll detect them. All I&#39;m saying is that a non privileged person will always detect more because they suffer them daily.&lt;/p&gt; &lt;p&gt;I understand that for you there is no issue using the word &lt;em&gt;master&lt;/em&gt;, there wasn&#39;t an issue for me either until I saw these projects doing the change, again I was blinded to the issue as I&#39;m not suffering it. That&#39;s because change is not meant for us, as we&#39;re not triggered by it. The change is targeted to the people that do perceive that &lt;code&gt;master&lt;/code&gt; is an offensive term. What we can do is empathize with them and follow this tiny tiny tiny gesture. It&#39;s the least we can do.&lt;/p&gt; &lt;p&gt;Think of a term that triggers you, such as &lt;em&gt;heil hitler&lt;/em&gt;, imagine that those words were being used to define the main branch of your code, and that everyday you sit in front of your computer you see them. You&#39;ll probably be reminded of the historic events, concepts, feelings that are tied to that term each time you see it, and being them quite negative it can slowly mine you. Therefore it&#39;s legit that you wouldn&#39;t want to be exposed to that negative effects.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;em&gt;I don&#39;t see who will benefit from this change&lt;/em&gt;: Probably the people that belongs to communities that are and have been under constant oppression for a very long time, in this case, specially the racialized ones which have suffered slavery.&lt;/p&gt; &lt;p&gt;Sadly you will probably won&#39;t see many the affected people speak in these discussions, first because there are not that many, sadly the IT world is dominated by middle aged, economically comfortable, white, cis, hetero, males. Small changes like this are meant to foster diversity in the community by allowing them being more comfortable. Secondly because when they see these debates they move on as they are so fed up on teaching privileged people of their privileges. They not only have to suffer the oppression, we also put the burden on their shoulders to teach us.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;As and ending thought, if you see yourself being specially troubled by the change, having a discomfort feeling and strong reactions. In my experience these signs are characteristic of privileged people that feel that their privileges are being threatened, I&#39;ve felt them myself countless times. When I feel it, +I usually do two things, fight them as strong as I can, or embrace them, analyze them, and go to the root of them. Depending on how much energy I have I go with the easy or the hard one. I&#39;m not saying that it&#39;s you&#39;re case, but it could be.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/git/&#34;&gt;Update the git flow to match my current one.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/git/#revert-a-commit&#34;&gt;Revert a commit.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;revert&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;commit_id
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/git/#get-interesting-stats-of-the-repo&#34;&gt;Get interesting stats of the repo.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://stackoverflow.com/questions/31190474/how-to-count-git-commits-per-user-in-a-date-range&#34;&gt;Number of commits of the last year per user&lt;/a&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;shortlog&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-sne&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--since&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;31 Dec 2020&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--before&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;31 Dec 2021&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can also use &lt;a href=&#34;https://github.com/casperdcl/git-fame#usage&#34;&gt;&lt;code&gt;git-fame&lt;/code&gt;&lt;/a&gt; to extract a more detailed report:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;git-fame&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--since&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;.year&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--cost&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;hour&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--loc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ins&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-w&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-M&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-C

&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Author&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;hrs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;loc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;coms&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;fils&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;distribution&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;:----------------&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;------:&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;------:&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;-------:&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;-------:&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;:----------------&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Lyz&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;28933&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;112&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;238&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;64&lt;/span&gt;.1/33.3/75.8&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;GitHub&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Action&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;16194&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;220&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;73&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;35&lt;/span&gt;.9/65.5/23.2&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Alexander&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Gil&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;9&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.0/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.3/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.3&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;n0rt3y5ur&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.0/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.3/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.3&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Guilherme&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Danno&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.0/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.3/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.3&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;lyz-code&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.0/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.3/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.0&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can use &lt;code&gt;pipx install git-fame&lt;/code&gt; to install it.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;park-programming&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/park_programming/&#34;&gt;Park programming&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the park programming concept.&lt;/p&gt; &lt;p&gt;Park programming is as you may guess, programming in parks. It includes guidelines on:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;How to park program&lt;/li&gt; &lt;li&gt;Finding the best spots&lt;/li&gt; &lt;li&gt;Finding the best times&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;sponsor&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/sponsor/&#34;&gt;Sponsor&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce sponsorship analysis.&lt;/p&gt; &lt;p&gt;It may arrive the moment in your life where &lt;a href=&#34;https://github.com/lyz-code/yamlfix/issues/185#issuecomment-1329276169&#34;&gt;someone wants to sponsor you&lt;/a&gt;. There are many sponsoring platforms you can use, each has their advantages and disadvantages.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Liberapay.&lt;/li&gt; &lt;li&gt;Ko-fi.&lt;/li&gt; &lt;li&gt;Buy me a coffee.&lt;/li&gt; &lt;li&gt;Github Sponsor.&lt;/li&gt; &lt;/ul&gt; &lt;table&gt; &lt;thead&gt; &lt;tr&gt; &lt;th&gt;&lt;/th&gt; &lt;th&gt;[Liberapay][3]&lt;/th&gt; &lt;th&gt;[Ko-fi][4]&lt;/th&gt; &lt;th&gt;[Buy Me a Coffee][6]&lt;/th&gt; &lt;th&gt;[Github Sponsor][7]&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Non-profit&lt;/td&gt; &lt;td&gt;[Yes][1]&lt;/td&gt; &lt;td&gt;No&lt;/td&gt; &lt;td&gt;No&lt;/td&gt; &lt;td&gt;No! (Microsoft!)&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Monthly fee&lt;/td&gt; &lt;td&gt;No&lt;/td&gt; &lt;td&gt;No&lt;/td&gt; &lt;td&gt;No&lt;/td&gt; &lt;td&gt;No&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Donation Commission&lt;/td&gt; &lt;td&gt;0%&lt;/td&gt; &lt;td&gt;0%&lt;/td&gt; &lt;td&gt;5%&lt;/td&gt; &lt;td&gt;Not clear&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Paid plan&lt;/td&gt; &lt;td&gt;No&lt;/td&gt; &lt;td&gt;[Yes][5]&lt;/td&gt; &lt;td&gt;No&lt;/td&gt; &lt;td&gt;No&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Payment Processors&lt;/td&gt; &lt;td&gt;Stripe, Paypal&lt;/td&gt; &lt;td&gt;Stripe, Paypal&lt;/td&gt; &lt;td&gt;Stripe, Standard Payout&lt;/td&gt; &lt;td&gt;Stripe&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;One time donations&lt;/td&gt; &lt;td&gt;[Possible but not user friendly][2]&lt;/td&gt; &lt;td&gt;Yes&lt;/td&gt; &lt;td&gt;Yes&lt;/td&gt; &lt;td&gt;Yes&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Membership&lt;/td&gt; &lt;td&gt;Yes&lt;/td&gt; &lt;td&gt;Yes&lt;/td&gt; &lt;td&gt;Yes&lt;/td&gt; &lt;td&gt;Yes&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Shop/Sales&lt;/td&gt; &lt;td&gt;No&lt;/td&gt; &lt;td&gt;Yes&lt;/td&gt; &lt;td&gt;No&lt;/td&gt; &lt;td&gt;No&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Based in&lt;/td&gt; &lt;td&gt;France&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;United States&lt;/td&gt; &lt;td&gt;United States?&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;+&lt;/td&gt; &lt;td&gt;Pay delay&lt;/td&gt; &lt;td&gt;Instant&lt;/td&gt; &lt;td&gt;Instant&lt;/td&gt; &lt;td&gt;Instant&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;User friendliness&lt;/td&gt; &lt;td&gt;OK&lt;/td&gt; &lt;td&gt;Good&lt;/td&gt; &lt;td&gt;Good&lt;/td&gt; &lt;td&gt;Good&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;&lt;a href=&#34;https://en.liberapay.com&#34;&gt;Liberapay&lt;/a&gt; is the only &lt;a href=&#34;https://en.liberapay.com/about/faq#differences&#34;&gt;non-profit&lt;/a&gt; recurrent donations platform. It&#39;s been the most recommended platform from the people I know from the open-source, activist environment.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://ko-fi.com/&#34;&gt;Ko-fi&lt;/a&gt; would be my next choice, as they don&#39;t do commissions on the donations and they support more features (that I don&#39;t need right now) than Liberapay.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;devops&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/ombi/&#34;&gt;DevOps&lt;/a&gt;&lt;/h2&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Ombi.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://ombi.io/&#34;&gt;Ombi&lt;/a&gt; is a self-hosted web application that automatically gives your shared Jellyfin users the ability to request content by themselves! Ombi can be linked to multiple TV Show and Movie DVR tools to create a seamless end-to-end experience for your users.&lt;/p&gt; &lt;p&gt;If Ombi is not for you, you may try &lt;a href=&#34;https://overseerr.dev/&#34;&gt;Overseerr&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;infrastructure-as-code&#34;&gt;Infrastructure as Code&lt;/h3&gt; &lt;h4 id=&#34;gitea&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/&#34;&gt;Gitea&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce gitea.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://gitea.io/en-us/&#34;&gt;Gitea&lt;/a&gt; is a community managed lightweight code hosting solution written in Go. It&#39;s the best self hosted Github alternative in my opinion.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;helmfile&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/helmfile/&#34;&gt;Helmfile&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Tweak the update process to make it more resilient.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Check that all the helm deployments are well deployed with &lt;code&gt;helm list -A | grep -v deployed&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Change the context to the production cluster before running the production steps&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/helmfile/#cannot-patch-x-field-is-immutable&#34;&gt;Fix Cannot patch X field is immutable error.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You may think that deleting the resource, usually a deployment or daemonset will fix it, but &lt;code&gt;helmfile apply&lt;/code&gt; will end without any error, the resource won&#39;t be recreated , and if you do a &lt;code&gt;helm list&lt;/code&gt;, the deployment will be marked as failed.&lt;/p&gt; &lt;p&gt;The solution we&#39;ve found is disabling the resource in the chart&#39;s values so that it&#39;s uninstalled an install it again.&lt;/p&gt; &lt;p&gt;This can be a problem with the resources that have persistence. To patch it, edit the volume resource with &lt;code&gt;kubectl edit pv -n namespace volume_pvc&lt;/code&gt;, change the &lt;code&gt;persistentVolumeReclaimPolicy&lt;/code&gt; to &lt;code&gt;Retain&lt;/code&gt;, apply the changes to uninstall, and when reinstalling configure the chart to use that volume (easier said than done).&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;ansible-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/&#34;&gt;Ansible Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#stop-running-docker-containers&#34;&gt;Stop running docker containers.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Get running containers&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;docker_host_info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;containers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;yes&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;register&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;docker_info&lt;/span&gt;

&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Stop running containers&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;docker_container&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;state&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;stopped&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;loop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;docker_info.containers&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;map(attribute=&#39;Id&#39;)&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#moving-a-file-remotely&#34;&gt;Moving a file remotely.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#speed-up-the-stat-module&#34;&gt;Speed up the stat module.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The &lt;code&gt;stat&lt;/code&gt; module calculates the checksum and the md5 of the file in order to get the required data. If you just want to check if the file exists use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Verify swapfile status&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;stat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;common_swapfile_location&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;get_checksum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;no&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;get_md5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;no&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;get_mime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;no&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;get_attributes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;no&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;register&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;swap_status&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;changed_when&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;not swap_status.stat.exists&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ansible_snippets/#get-the-hosts-of-a-dynamic-ansible-inventory&#34;&gt;Get the hosts of a dynamic ansible inventory.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ansible-inventory&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;environments/production&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--graph
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can also use the &lt;code&gt;--list&lt;/code&gt; flag to get more info of the hosts.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;infrastructure-solutions&#34;&gt;Infrastructure Solutions&lt;/h3&gt; &lt;h4 id=&#34;krew&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aws_snippets/&#34;&gt;Krew&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/aws_snippets/#find-if-external-ip-belongs-to-you&#34;&gt;Find if external IP belongs to you.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can list the network interfaces that match the IP you&#39;re searching for&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;aws&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ec2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;describe-network-interfaces&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--filters&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;Name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;association.public-ip,Values&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;{{ your_ip_address}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce krew.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/krew&#34;&gt;Krew&lt;/a&gt; is a tool that makes it easy to use kubectl plugins. Krew helps you discover plugins, install and manage them on your machine. It is similar to tools like apt, dnf or brew.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;aws-savings-plan&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubectl/kubectl_commands/&#34;&gt;AWS Savings plan&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubectl/kubectl_commands/#create-a-configmap-from-a-file&#34;&gt;Create a configmap from a file.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;create&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;configmap&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;configmap_name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--from-file&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;path/to/file&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubectl/kubectl_commands/#restart-pods-without-taking-the-service-down&#34;&gt;Restart pods without taking the service down.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rollout&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;deployment&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;deployment_name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce Ksniff.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/eldadru/ksniff&#34;&gt;Ksniff&lt;/a&gt; is a Kubectl plugin to ease sniffing on kubernetes pods using tcpdump and wireshark.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce AWS Savings plan.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://docs.aws.amazon.com/savingsplans/latest/userguide/what-is-savings-plans.html&#34;&gt;Saving plans&lt;/a&gt; offer a flexible pricing model that provides savings on AWS usage. You can save up to 72 percent on your AWS compute workloads.&lt;/p&gt; &lt;p&gt;!!! note &#34;Please don&#39;t make Jeff Bezos even richer, try to pay as less money to AWS as you can.&#34;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;mizu&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/mizu/&#34;&gt;Mizu&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce mizu.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://getmizu.io/&#34;&gt;Mizu&lt;/a&gt; is an API Traffic Viewer for Kubernetes, think &lt;code&gt;TCPDump&lt;/code&gt; and Chrome Dev Tools combined.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;kubectl&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubectl/kubectl/&#34;&gt;Kubectl&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubectl/kubectl/#port-forward-/-tunnel-to-an-internal-service&#34;&gt;Port forward / Tunnel to an internal service.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you have a service running in kubernetes and you want to directly access it instead of going through the usual path, you can use &lt;code&gt;kubectl port-forward&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;&lt;code&gt;kubectl port-forward&lt;/code&gt; allows using resource name, such as a pod name, service replica set or deployment, to select the matching resource to port forward to. For example, the next commands are equivalent:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;port-forward&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mongo-75f59d57f4-4nd6q&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;28015&lt;/span&gt;:27017
kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;port-forward&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;deployment/mongo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;28015&lt;/span&gt;:27017
kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;port-forward&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;replicaset/mongo-75f59d57f4&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;28015&lt;/span&gt;:27017
kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;port-forward&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;service/mongo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;28015&lt;/span&gt;:27017
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The output is similar to this:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Forwarding&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;from&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;127&lt;/span&gt;.0.0.1:28015&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;27017&lt;/span&gt;
Forwarding&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;from&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;::1&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;:28015&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;27017&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you don&#39;t need a specific local port, you can let &lt;code&gt;kubectl&lt;/code&gt; choose and allocate the local port and thus relieve you from having to manage local port conflicts, with the slightly simpler syntax:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;port-forward&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;deployment/mongo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;:27017

Forwarding&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;from&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;127&lt;/span&gt;.0.0.1:63753&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;27017&lt;/span&gt;
Forwarding&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;from&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;::1&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;:63753&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;27017&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubectl/kubectl/#run-a-command-against-a-specific-context&#34;&gt;Run a command against a specific context.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you have multiple contexts and you want to be able to run commands against a context that you have access to but is not your active context you can use the &lt;code&gt;--context&lt;/code&gt; global option for all &lt;code&gt;kubectl&lt;/code&gt; commands:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pods&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--context&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;context_B&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To get a list of available contexts use &lt;code&gt;kubectl config get-contexts&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;eks&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/aws/eks/&#34;&gt;EKS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/aws/eks/#pod-limit-per-node&#34;&gt;Pod limit per node.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;AWS EKS supports native VPC networking with the Amazon VPC Container Network Interface (CNI) plugin for Kubernetes. Using this plugin allows Kubernetes Pods to have the same IP address inside the pod as they do on the VPC network.&lt;/p&gt; &lt;p&gt;This is a great feature but it introduces a limitation in the number of Pods per EC2 Node instance. Whenever you deploy a Pod in the EKS worker Node, EKS creates a new IP address from VPC subnet and attach to the instance.&lt;/p&gt; &lt;p&gt;The formula for defining the maximum number of pods per instance is as follows:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;N * (M-1) + 2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;N&lt;/code&gt; is the number of Elastic Network Interfaces (ENI) of the instance type.&lt;/li&gt; &lt;li&gt;&lt;code&gt;M&lt;/code&gt; is the number of IP addresses of a single ENI.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;So, for &lt;code&gt;t3.small&lt;/code&gt;, this calculation is &lt;code&gt;3 * (4-1) + 2 = 11&lt;/code&gt;. For a list of all the instance types and their limits see &lt;a href=&#34;https://github.com/awslabs/amazon-eks-ami/blob/master/files/eni-max-pods.txt&#34;&gt;this document&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;debugging&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/kubernetes_debugging/&#34;&gt;Debugging&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: How to debug kubernetes network traffic.&lt;/p&gt; &lt;p&gt;Sometimes you need to monitor the network traffic that goes between pods to solve an issue. There are different ways to see it:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/mizu/&#34;&gt;Using Mizu&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/kubernetes_debugging/#running-tcpdump-against-a-running-container&#34;&gt;Running tcpdump against a running container&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/ksniff/&#34;&gt;Using ksniff&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/kubernetes_debugging/#using-ephemeral-debug-containers&#34;&gt;Using ephemeral debug containers&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Of all the solutions, the cleaner and easier is to use &lt;a href=&#34;https://lyz-code.github.io/blue-book/mizu/&#34;&gt;Mizu&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;waf&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aws_waf/&#34;&gt;WAF&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: How to extract information from AWS WAF.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://aws.amazon.com/waf/&#34;&gt;AWS WAF&lt;/a&gt; is a web application firewall that helps protect your web applications or APIs against common web exploits and bots that may affect availability, compromise security, or consume excessive resources. AWS WAF gives you control over how traffic reaches your applications by enabling you to create security rules that control bot traffic and block common attack patterns, such as SQL injection or cross-site scripting. You can also customize rules that filter out specific traffic patterns.&lt;/p&gt; &lt;p&gt;In the article there are many queries you can do on it&#39;s data and a workflow to understand your traffic.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;continuous-integration&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/mdformat/&#34;&gt;Continuous Integration&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce MDFormat.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://mdformat.readthedocs.io/en/stable/&#34;&gt;MDFormat&lt;/a&gt; is an opinionated Markdown formatter that can be used to enforce a consistent style in Markdown files. Mdformat is a Unix-style command-line tool as well as a Python library.&lt;/p&gt; &lt;p&gt;The features/opinions of the formatter include:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Consistent indentation and whitespace across the board&lt;/li&gt; &lt;li&gt;Always use ATX style headings&lt;/li&gt; &lt;li&gt;Move all link references to the bottom of the document (sorted by label)&lt;/li&gt; &lt;li&gt;Reformat indented code blocks as fenced code blocks&lt;/li&gt; &lt;li&gt;Use 1. as the ordered list marker if possible, also for noninitial list items.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;It&#39;s based on the &lt;a href=&#34;https://markdown-it-py.readthedocs.io/en/latest/index.html&#34;&gt;&lt;code&gt;markdown-it-py&lt;/code&gt;&lt;/a&gt; Markdown parser, which is a Python implementation of &lt;a href=&#34;https://github.com/markdown-it/markdown-it&#34;&gt;&lt;code&gt;markdown-it&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/mdformat/#issues&#34;&gt;Issues.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;It doesn&#39;t yet &lt;a href=&#34;https://github.com/executablebooks/mdformat/issues/309&#34;&gt;support admonitions&lt;/a&gt;&lt;/li&gt; &lt;li&gt;You can&#39;t &lt;a href=&#34;https://github.com/executablebooks/mdformat/issues/359&#34;&gt;ignore some files&lt;/a&gt;, nor &lt;a href=&#34;https://github.com/executablebooks/mdformat/issues/53&#34;&gt;some part of the file&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;drone&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/flakeheaven/&#34;&gt;Drone&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Deprecate flakehell in favour of flakeheaven.&lt;/p&gt; &lt;p&gt;It&#39;s a fork maintained by the community, instead of an absent code dictator.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce Flakeheaven.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/flakeheaven/flakeheaven&#34;&gt;Flakeheaven&lt;/a&gt; is a &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/flake8/&#34;&gt;Flake8&lt;/a&gt; wrapper to make it cool. The community maintained fork of flakehell.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce Drone.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.drone.io/&#34;&gt;Drone&lt;/a&gt; is a modern Continuous Integration platform that empowers busy teams to automate their build, test and release workflows using a powerful, cloud native pipeline engine.&lt;/p&gt; &lt;p&gt;Check how to install it &lt;a href=&#34;https://lyz-code.github.io/blue-book/drone/#installation&#34;&gt;here&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;automating-processes&#34;&gt;Automating Processes&lt;/h3&gt; &lt;h4 id=&#34;cruft&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/cruft/&#34;&gt;cruft&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/cruft/#issues&#34;&gt;Unable to interpret changes between current project and cookiecutter template as unicode.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Typically a result of hidden binary files in project folder. Maybe you have a hook that initializes the &lt;code&gt;.git&lt;/code&gt; directory, don&#39;t do that.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Use &lt;code&gt;skip&lt;/code&gt; to avoid problems with &lt;code&gt;.git&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Since &lt;code&gt;2.10.0&lt;/code&gt; you can add a &lt;code&gt;skip&lt;/code&gt; category inside the &lt;code&gt;.cruft.json&lt;/code&gt;, so that it doesn&#39;t check that directory:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;template&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;xxx&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;commit&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;xxx&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;checkout&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;context&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;cookiecutter&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;...&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;directory&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;skip&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;.git&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;renovate&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/renovate/&#34;&gt;renovate&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Renovate.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://docs.renovatebot.com/&#34;&gt;Renovate&lt;/a&gt; is a program that does automated dependency updates. Multi-platform and multi-language.&lt;/p&gt; &lt;p&gt;Why use Renovate?&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Get pull requests to update your dependencies and lock files.&lt;/li&gt; &lt;li&gt;Reduce noise by scheduling when Renovate creates PRs.&lt;/li&gt; &lt;li&gt;Renovate finds relevant package files automatically, including in monorepos.&lt;/li&gt; &lt;li&gt;You can customize the bot&#39;s behavior with configuration files.&lt;/li&gt; &lt;li&gt;Share your configuration with ESLint-like config presets.&lt;/li&gt; &lt;li&gt;Get replacement PRs to migrate from a deprecated dependency to the community suggested replacement (npm packages only).&lt;/li&gt; &lt;li&gt;Open source.&lt;/li&gt; &lt;li&gt;Popular (more than 9.7k stars and 1.3k forks)&lt;/li&gt; &lt;li&gt;Beautifully integrate with main Git web applications (Gitea, Gitlab, Github).&lt;/li&gt; &lt;li&gt;It supports most important languages: Python, Docker, Kubernetes, Terraform, Ansible, Node, ...&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;storage&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/storage/&#34;&gt;Storage&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce storage.&lt;/p&gt; &lt;p&gt;I have a server at home to host some services for my closest ones. The server is an &lt;a href=&#34;https://www.intel.com/content/www/us/en/products/details/nuc.html&#34;&gt;Intel NUC&lt;/a&gt; which is super awesome in terms of electric consumption, CPU and RAM versus cost. The downside is that it has no hard drive to store the services data. It does have some USB ports to connect external hard drives though. As the data kept growing I started buying bigger drives. While it was affordable I purchased two so as to have one to store the backup of the data. The problem came when it became unaffordable for me. Then I took the &lt;em&gt;good idea&lt;/em&gt; to assume that I could only have one drive of 16TB with my data. Obviously the inevitable happened. The hard drive died and those 10TB of data that were not stored in any backup were lost.&lt;/p&gt; &lt;p&gt;Luckily enough, it was not unique data like personal photos. The data could be regenerated by manual processes at the cost of precious time (I&#39;m still suffering this &lt;code&gt;:(&lt;/code&gt;). But every cloud has a silver lining, this failure gave me the energy and motivation to improve my home architecture. To prevent this from happening again, the solution needs to be:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Robust: If disks die I will have time to replace them before data is lost.&lt;/li&gt; &lt;li&gt;Flexible: It needs to expand as the data grows.&lt;/li&gt; &lt;li&gt;Not very expensive.&lt;/li&gt; &lt;li&gt;Easy to maintain.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;There are two types of solutions to store data:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;On one host: All disks are attached to a server and the storage capacity is shared to other devices by the local network.&lt;/li&gt; &lt;li&gt;Distributed: The disks are attached to many servers and they work together to provide the storage through the local network.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;A &lt;a href=&#34;https://lyz-code.github.io/blue-book/nas/&#34;&gt;NAS&lt;/a&gt; server represents the first solution, while systems like &lt;a href=&#34;https://ceph.io/en/&#34;&gt;Ceph&lt;/a&gt; or &lt;a href=&#34;https://www.gluster.org/&#34;&gt;GlusterFS&lt;/a&gt; over &lt;a href=&#34;https://www.odroid.co.uk/ODROID-HC4&#34;&gt;Odroid HC4&lt;/a&gt; fall into the second.&lt;/p&gt; &lt;p&gt;Both are robust and flexible but I&#39;m more inclined towards building a &lt;a href=&#34;https://lyz-code.github.io/blue-book/nas/&#34;&gt;NAS&lt;/a&gt; because it can hold the amount of data that I need, it&#39;s easier to maintain and the underlying technology has been more battle proven throughout the years.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;nas&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/nas/&#34;&gt;NAS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce NAS.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Network-attached_storage&#34;&gt;Network-attached storage&lt;/a&gt; or NAS, is a computer data storage server connected to a computer network providing data access to many other devices. Basically a computer where you can attach many hard drives.&lt;/p&gt; &lt;p&gt;I&#39;ve done an analysis to choose what solution I&#39;m going to build in terms of:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Software: Whether to use &lt;a href=&#34;https://lyz-code.github.io/blue-book/nas/#truenas&#34;&gt;TrueNAS&lt;/a&gt;, &lt;a href=&#34;https://lyz-code.github.io/blue-book/nas/#unraid&#34;&gt;Unraid&lt;/a&gt; or &lt;a href=&#34;https://lyz-code.github.io/blue-book/nas/#debian-with-zfs&#34;&gt;Debian with ZFS&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/nas/#disks&#34;&gt;Disks&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;More will come in the next days.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/nas/#ram&#34;&gt;Analyze RAM to buy.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Most &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/&#34;&gt;ZFS&lt;/a&gt; resources suggest using ECC RAM. The provider gives me two options:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Kingston Server Premier DDR4 3200MHz 16GB CL22&lt;/li&gt; &lt;li&gt;Kingston Server Premier DDR4 2666MHz 16GB CL19&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;I&#39;ll go with two modules of 3200MHz CL22 because it has a smaller &lt;a href=&#34;https://lyz-code.github.io/blue-book/ram/#speed&#34;&gt;RAM latency&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/nas/#motherboard&#34;&gt;Analyze motherboard to buy.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;After reading these reviews(&lt;a href=&#34;https://reviewsgarage.com/best-motherboards-for-nas/&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;https://pcper.com/2020/03/asrock-x570m-pro4-micro-atx-motherboard-review/&#34;&gt;2&lt;/a&gt;) I&#39;ve come to the decision to purchase the &lt;a href=&#34;https://www.asrock.com/MB/AMD/X570M%20Pro4/index.asp&#34;&gt;ASRock X570M Pro4&lt;/a&gt; because, It supports:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;8 x SATA3 disks&lt;/li&gt; &lt;li&gt;2 x M.2 disks&lt;/li&gt; &lt;li&gt;4 x DDR4 RAM slots with speeds up to 4200+ and ECC support&lt;/li&gt; &lt;li&gt;1 x AMD AM4 Socket Ryzen™ 2000, 3000, 4000 G-Series, 5000 and 5000 G-Series Desktop Processors&lt;/li&gt; &lt;li&gt;Supports NVMe SSD as boot disks&lt;/li&gt; &lt;li&gt;Micro ATX Form Factor.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;And it gives me room enough to grow:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;It supports PCI 4.0 for the M.2 which is said to be capable of perform twice the speed compared to previous 3&lt;sup&gt;rd&lt;/sup&gt; generation. the chosen M2 are of 3&lt;sup&gt;rd&lt;/sup&gt; generation, so if I need more speed I can change them.&lt;/li&gt; &lt;li&gt;I&#39;m only going to use 2 slots of RAM giving me 32GB, but I could grow 32 more easily.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/nas/#cpu&#34;&gt;Analyze CPU to buy.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;After doing some &lt;a href=&#34;https://lyz-code.github.io/blue-book/cpu/&#34;&gt;basic research&lt;/a&gt; I&#39;m between:&lt;/p&gt; &lt;table&gt; &lt;thead&gt; &lt;tr&gt; &lt;th&gt;Property&lt;/th&gt; &lt;th&gt;Ryzen 7 5800x&lt;/th&gt; &lt;th&gt;Ryzen 5 5600x&lt;/th&gt; &lt;th&gt;Ryzen 7 5700x&lt;/th&gt; &lt;th&gt;Ryzen 5 5600G&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Cores&lt;/td&gt; &lt;td&gt;8&lt;/td&gt; &lt;td&gt;6&lt;/td&gt; &lt;td&gt;8&lt;/td&gt; &lt;td&gt;6&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Threads&lt;/td&gt; &lt;td&gt;16&lt;/td&gt; &lt;td&gt;12&lt;/td&gt; &lt;td&gt;16&lt;/td&gt; &lt;td&gt;12&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Clock&lt;/td&gt; &lt;td&gt;3.8&lt;/td&gt; &lt;td&gt;3.7&lt;/td&gt; &lt;td&gt;3.4&lt;/td&gt; &lt;td&gt;3.9&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Socket&lt;/td&gt; &lt;td&gt;AM4&lt;/td&gt; &lt;td&gt;AM4&lt;/td&gt; &lt;td&gt;AM4&lt;/td&gt; &lt;td&gt;AM4&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;PCI&lt;/td&gt; &lt;td&gt;4.0&lt;/td&gt; &lt;td&gt;4.0&lt;/td&gt; &lt;td&gt;4.0&lt;/td&gt; &lt;td&gt;3.0&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Thermal&lt;/td&gt; &lt;td&gt;Not included&lt;/td&gt; &lt;td&gt;Wraith Stealth&lt;/td&gt; &lt;td&gt;Not included&lt;/td&gt; &lt;td&gt;Wraith Stealth&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Default TDP&lt;/td&gt; &lt;td&gt;105W&lt;/td&gt; &lt;td&gt;65W&lt;/td&gt; &lt;td&gt;65W&lt;/td&gt; &lt;td&gt;65W&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;System Mem spec&lt;/td&gt; &lt;td&gt;&amp;gt;= 3200 MHz&lt;/td&gt; &lt;td&gt;&amp;gt;= 3200 MHz&lt;/td&gt; &lt;td&gt;&amp;gt;= 3200 MHz&lt;/td&gt; &lt;td&gt;&amp;gt;= 3200 MHz&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Mem type&lt;/td&gt; &lt;td&gt;DDR4&lt;/td&gt; &lt;td&gt;DDR4&lt;/td&gt; &lt;td&gt;DDR4&lt;/td&gt; &lt;td&gt;DDR4&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Price&lt;/td&gt; &lt;td&gt;315&lt;/td&gt; &lt;td&gt;232&lt;/td&gt; &lt;td&gt;279&lt;/td&gt; &lt;td&gt;179&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;The data was extracted from &lt;a href=&#34;https://www.amd.com/en/products/specifications/compare/processors/10466,11826,10471,11176&#34;&gt;AMD&#39;s official page&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;They all support the chosen RAM and the motherboard.&lt;/p&gt; &lt;p&gt;I&#39;m ruling out Ryzen 7 5800x because it&#39;s too expensive both on monetary and power consumption terms. Also ruling out Ryzen 5 5600G because it has comparatively bad properties.&lt;/p&gt; &lt;p&gt;Between Ryzen 5 5600x and Ryzen 7 5700x, after checking these comparisons (&lt;a href=&#34;https://nanoreview.net/en/cpu-compare/amd-ryzen-7-5700x-vs-amd-ryzen-5-5600x&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;https://www.amd.com/en/products/specifications/compare/processors/10466,11826,10471,11176&#34;&gt;2&lt;/a&gt;) it looks like:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Single core performance is similar.&lt;/li&gt; &lt;li&gt;7 wins when all cores are involved.&lt;/li&gt; &lt;li&gt;7 is more power efficient.&lt;/li&gt; &lt;li&gt;7 is better rated.&lt;/li&gt; &lt;li&gt;7 is newer (1.5 years).&lt;/li&gt; &lt;li&gt;7 has around 3.52 GB/s (7%) higher theoretical RAM memory bandwidth&lt;/li&gt; &lt;li&gt;They have the same cache&lt;/li&gt; &lt;li&gt;7 has 5 degrees less of max temperature&lt;/li&gt; &lt;li&gt;They both support ECC&lt;/li&gt; &lt;li&gt;5 has a greater market share&lt;/li&gt; &lt;li&gt;5 is 47$ cheaper&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;I think that for 47$ it&#39;s work the increase on cores and theoretical RAM memory bandwidth.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/nas/#cpu-cooler&#34;&gt;Analyze CPU coolers to buy.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It looks that the &lt;a href=&#34;https://lyz-code.github.io/blue-book/cpu/#quick-shopping-tips&#34;&gt;Ryzen CPUs don&#39;t require a cooler to work well&lt;/a&gt;. Usually it adds another 250W to the consumption. I don&#39;t plan to overclock it and I&#39;ve heard that ZFS doesn&#39;t use too much CPU, so I&#39;ll start without it and monitor the temperature.&lt;/p&gt; &lt;p&gt;If I were to take one, I&#39;d go with air cooling with something like the &lt;a href=&#34;https://www.bequiet.com/en/cpucooler/1376&#34;&gt;Dark Rock 4&lt;/a&gt; but I&#39;ve also read that Noctua are a good provider.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/nas/#server-case&#34;&gt;Analyze server cases to buy.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I&#39;m ruling out the next ones:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.fractal-design.com/products/cases/define/define-r6/blackout/&#34;&gt;Fractal Design R6&lt;/a&gt;: More expensive than the Node 804 and it doesn&#39;t have hot swappable disks.&lt;/li&gt; &lt;li&gt;Silverstone Technology SST-CS381: Even though it&#39;s gorgeous it&#39;s too expensive.&lt;/li&gt; &lt;li&gt;Silverstone DS380: It only supports Mini-ITX which I don&#39;t have.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The remaining are:&lt;/p&gt; &lt;table&gt; &lt;thead&gt; &lt;tr&gt; &lt;th&gt;Model&lt;/th&gt; &lt;th&gt;Fractal Node 804&lt;/th&gt; &lt;th&gt;Silverstone CS380&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Form factor&lt;/td&gt; &lt;td&gt;Micro - ATX&lt;/td&gt; &lt;td&gt;Mid tower&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Motherboard&lt;/td&gt; &lt;td&gt;Micro ATX&lt;/td&gt; &lt;td&gt;Micro ATX&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Drive bays&lt;/td&gt; &lt;td&gt;8 x 3.5&#34;, 2 x 2.5&#34;&lt;/td&gt; &lt;td&gt;8 x 3.5&#34;, 2 x 5.25&#34;&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Hot-swap&lt;/td&gt; &lt;td&gt;No&lt;/td&gt; &lt;td&gt;yes&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Expansion Slots&lt;/td&gt; &lt;td&gt;5&lt;/td&gt; &lt;td&gt;7&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;CPU cooler height&lt;/td&gt; &lt;td&gt;160mm&lt;/td&gt; &lt;td&gt;146 mm&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;PSU compatibility&lt;/td&gt; &lt;td&gt;ATX&lt;/td&gt; &lt;td&gt;ATX&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Fans&lt;/td&gt; &lt;td&gt;Front: 4, Top: 4, Rear 3&lt;/td&gt; &lt;td&gt;Side: 2, Rear: 1&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Price&lt;/td&gt; &lt;td&gt;115&lt;/td&gt; &lt;td&gt;184&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Size&lt;/td&gt; &lt;td&gt;34 x 31 x 39 cm&lt;/td&gt; &lt;td&gt;35 x 28 x 21 cm&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;I like the Fractal Node 804 better and it&#39;s cheaper.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Choose the Power Supply Unit and CPU cooler.&lt;/p&gt; &lt;p&gt;After doing some &lt;a href=&#34;https://lyz-code.github.io/blue-book/cpu/#cpu-coolers&#34;&gt;basic research&lt;/a&gt; I&#39;ve chosen the &lt;a href=&#34;https://www.bequiet.com/en/cpucooler/1376&#34;&gt;Dark Rock 4&lt;/a&gt; but just because the &lt;a href=&#34;https://www.enermaxeu.com/products/cpu-cooling/air-cooling/ets-t50-axe/&#34;&gt;Enermax ETS-T50 AXE Silent Edition&lt;/a&gt; doesn&#39;t fit my case :(.&lt;/p&gt; &lt;p&gt;Using &lt;a href=&#34;https://pcpartpicker.com/list/&#34;&gt;PCPartPicker&lt;/a&gt; I&#39;ve seen that with 4 disks it consumes approximately 264W, when I have the 8 disks, it will consume up to 344W, if I want to increase the ram then it will reach 373W. So in theory I can go with a 400W power supply unit.&lt;/p&gt; &lt;p&gt;You need to make sure that it has enough wires to connect to all the disks. Although that usually is not a problem as there are adapters:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.amazon.com/CB-44SATA-Individually-Sleeved-Connector-Premium/dp/B0036ORCIA/ref=sr_1_13?ie=UTF8&amp;amp;qid=1409942557&amp;amp;sr=8-13&amp;amp;keywords=sleeved+molex+to+sata&amp;amp;tag=linus21-20&#34;&gt;Molex to sata&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.amazon.com/dp/B0086OGN9E/ref=wl_it_dp_o_pd_nS_ttl?_encoding=UTF8&amp;amp;colid=2IW6VX45YF9B0&amp;amp;coliid=I1QUIF5VMSN2SG&amp;amp;psc=1&amp;amp;tag=linus21-20&#34;&gt;Sata to sata&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;After an &lt;a href=&#34;https://lyz-code.github.io/blue-book/psu/&#34;&gt;analysis on the different power supply units&lt;/a&gt;, I&#39;ve decided to go with &lt;a href=&#34;https://www.bequiet.com/en/powersupply/1251&#34;&gt;Be Quiet! Straight Power 11 450W Gold&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;openzfs&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/&#34;&gt;OpenZFS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#learning&#34;&gt;Learning.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I&#39;ve found that learning about ZFS was an interesting, intense and time consuming task. If you want a quick overview check &lt;a href=&#34;https://yewtu.be/watch?v=MsY-BafQgj4&#34;&gt;this video&lt;/a&gt;. If you prefer to read, head to the awesome &lt;a href=&#34;https://pthree.org/2012/04/17/install-zfs-on-debian-gnulinux/&#34;&gt;Aaron Toponce&lt;/a&gt; articles and read all of them sequentially, each is a jewel. The &lt;a href=&#34;https://openzfs.github.io/openzfs-docs/&#34;&gt;docs&lt;/a&gt; on the other hand are not that pleasant to read. For further information check &lt;a href=&#34;https://jrs-s.net/category/open-source/zfs/&#34;&gt;JRS articles&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#storage-planning&#34;&gt;Storage planning.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;There are many variables that affect the number and type of disks, you first need to have an idea of what kind of data you want to store and what use are you going to give to that data.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#robustness&#34;&gt;Robustness&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#preventing-concurrent-disk-failures&#34;&gt;Preventing concurrent disk failures&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#choosing-the-disks-to-hold-data&#34;&gt;Choosing the disks to hold data.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Analysis on how to choose the disks taking into account:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#data-disk-speed&#34;&gt;Disk speed&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#data-disk-load&#34;&gt;Disk load&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#data-disk-type&#34;&gt;Disk type&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#data-disk-homogeneity&#34;&gt;Disk homogeneity&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#data-disk-warranty&#34;&gt;Disk Warranty&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#data-disk-brand&#34;&gt;Disk Brands&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The conclusions are that I&#39;m more interested on the 5400 RPM drives, but of all the NAS disks available to purchase only the WD RED of 8TB use it, and they use the SMR technology, so they aren&#39;t a choice.&lt;/p&gt; &lt;p&gt;The disk prices offered by my cheapest provider are:&lt;/p&gt; &lt;table&gt; &lt;thead&gt; &lt;tr&gt; &lt;th&gt;Disk&lt;/th&gt; &lt;th&gt;Size&lt;/th&gt; &lt;th&gt;Price&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Seagate IronWolf&lt;/td&gt; &lt;td&gt;8TB&lt;/td&gt; &lt;td&gt;225$&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Seagate IronWolf Pro&lt;/td&gt; &lt;td&gt;8TB&lt;/td&gt; &lt;td&gt;254$&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;WD Red Plus&lt;/td&gt; &lt;td&gt;8TB&lt;/td&gt; &lt;td&gt;265$&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Seagate Exos 7E8&lt;/td&gt; &lt;td&gt;8TB&lt;/td&gt; &lt;td&gt;277$&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;WD Red Pro&lt;/td&gt; &lt;td&gt;8TB&lt;/td&gt; &lt;td&gt;278$&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;WD Red Plus has 5,640 RPM which is different than the rest, so it&#39;s ruled out. Between the IronWolf and IronWolf Pro, they offer 180MB/s and 214MB/s respectively. The Seagate Exos 7E8 provides much better performance than the WD Red Pro so I&#39;m afraid that WD is out of the question.&lt;/p&gt; &lt;p&gt;There are three possibilities in order to have two different brands. Imagining we want 4 disks:&lt;/p&gt; &lt;table&gt; &lt;thead&gt; &lt;tr&gt; &lt;th&gt;Combination&lt;/th&gt; &lt;th&gt;Total Price&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;IronWolf + IronWolf Pro&lt;/td&gt; &lt;td&gt;958$&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;IronWolf + Exos 7E8&lt;/td&gt; &lt;td&gt;1004$ (+46$ +4.5%)&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;IronWolf Pro + Exos 7E8&lt;/td&gt; &lt;td&gt;1062$ (+54$ +5.4%)&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;In terms of:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Consumption: both IronWolfs are equal, the Exos uses 2.7W more on normal use and uses 0.2W less on rest.&lt;/li&gt; &lt;li&gt;Warranty: IronWolf has only 3 years, the others 5.&lt;/li&gt; &lt;li&gt;Speed: Ironwolf has 210MB/s, much less than the Pro (255MB/s) and Exos (249MB/s), which are more similar.&lt;/li&gt; &lt;li&gt;Sostenibility: The Exos disks are much more robust (more workload, MTBF and Warranty).&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;I&#39;d say that for 104$ it makes sense to go with the IronWolf Pro + Exos 7E8 combination.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#choosing-the-disks-for-the-cache&#34;&gt;Choosing the disks for the cache.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Using a ZLOG greatly improves the &lt;a href=&#34;https://www.servethehome.com/exploring-best-zfs-zil-slog-ssd-intel-optane-nand/&#34;&gt;writing speed&lt;/a&gt;, equally using an SSD disk for the L2ARC cache improves the read speeds and improves the health of the rotational disks.&lt;/p&gt; &lt;p&gt;The best M.2 NVMe SSD for NAS caching are the ones that have enough capacity to actually make a difference to overall system performance. It also requires a good endurance rating for better reliability and longer lifespan, and you should look for a drive with a specific NAND technology if possible.&lt;/p&gt; &lt;p&gt;I&#39;ve made an analysis based on:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#cache-disk-nand-technology&#34;&gt;Cache disk NAND technology&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#dwpd&#34;&gt;DWPD&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;As conclusion, I’d recommend the Western Digital Red SN700, which has a good 1 DWPD endurance rating, is available in sizes up to 4TB, and is using SLC NAND technology, which is great for enhancing reliability through heavy caching workloads. A close second place goes to the Seagate IronWolf 525, which has similar specifications to the SN700 but utilizes TLC.&lt;/p&gt; &lt;table&gt; &lt;thead&gt; &lt;tr&gt; &lt;th&gt;Disk&lt;/th&gt; &lt;th&gt;Size&lt;/th&gt; &lt;th&gt;Speed&lt;/th&gt; &lt;th&gt;Endurance&lt;/th&gt; &lt;th&gt;Warranty&lt;/th&gt; &lt;th&gt;Tech&lt;/th&gt; &lt;th&gt;Price&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;WD Red SN700&lt;/td&gt; &lt;td&gt;500 GB&lt;/td&gt; &lt;td&gt;3430MB/s&lt;/td&gt; &lt;td&gt;1 DWPD&lt;/td&gt; &lt;td&gt;5 years&lt;/td&gt; &lt;td&gt;SLC&lt;/td&gt; &lt;td&gt;73$&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;SG IronWolf 525&lt;/td&gt; &lt;td&gt;500 GB&lt;/td&gt; &lt;td&gt;5000MB/s&lt;/td&gt; &lt;td&gt;0.8 DWPD&lt;/td&gt; &lt;td&gt;5 years&lt;/td&gt; &lt;td&gt;TLC&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;WD Red SN700&lt;/td&gt; &lt;td&gt;1 TB&lt;/td&gt; &lt;td&gt;3430MB/s&lt;/td&gt; &lt;td&gt;1 DWPD&lt;/td&gt; &lt;td&gt;5 years&lt;/td&gt; &lt;td&gt;SLC&lt;/td&gt; &lt;td&gt;127$&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;SG IronWolf 525&lt;/td&gt; &lt;td&gt;1 TB&lt;/td&gt; &lt;td&gt;5000MB/s&lt;/td&gt; &lt;td&gt;0.8 DWPD&lt;/td&gt; &lt;td&gt;5 years&lt;/td&gt; &lt;td&gt;TLC&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#choosing-the-cold-spare-disks&#34;&gt;Choosing the cold spare disks.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It&#39;s good to think how much time you want to have your raids to be inconsistent once a drive has failed.&lt;/p&gt; &lt;p&gt;In my case, for the data I want to restore the raid as soon as I can, therefore I&#39;ll buy another rotational disk. For the SSDs I have more confidence that they won&#39;t break so I don&#39;t feel like having a spare one.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;monitoring&#34;&gt;Monitoring&lt;/h3&gt; &lt;h4 id=&#34;prometheus&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/prometheus/&#34;&gt;Prometheus&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/prometheus/#accessing-prometheus-metrics-through-python&#34;&gt;Accessing Prometheus metrics through python.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;requests&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;requests&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;http://127.0.0.1:9090/api/v1/query&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;params&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;query&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;container_cpu_user_seconds_total&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;alertmanager&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/alertmanager/&#34;&gt;AlertManager&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/alertmanager/#silences&#34;&gt;Use regular expressions in silences.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To silence an alert with a regular expression use the matcher &lt;code&gt;alertname=~&#34;.*Condition&#34;&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;hardware&#34;&gt;Hardware&lt;/h3&gt; &lt;h4 id=&#34;cpu&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/cpu/&#34;&gt;CPU&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce CPU, attributes and how to buy it.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Central_processing_unit&#34;&gt;A central processing unit or CPU&lt;/a&gt;, also known as the brain of the server, is the electronic circuitry that executes instructions comprising a computer program. The CPU performs basic arithmetic, logic, controlling, and input/output (I/O) operations specified by the instructions in the program.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/cpu/#market-analysis&#34;&gt;Add the market analysis.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/cpu/#cpu-coolers&#34;&gt;Analyze the cpu coolers.&lt;/a&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/cpu/#cpu-thermal-paste&#34;&gt;Analyze the use of cpu thermal paste.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Thermal paste is designed to minimize microscopic air gaps and irregularities between the surface of the cooler and the CPU&#39;s IHS (integrated heat spreader), the piece of metal which is built into the top of the processor.&lt;/p&gt; &lt;p&gt;Good thermal paste can have a profound impact on your performance, because it will allow your processor to transfer more of its waste heat to your cooler, keeping your processor running cool.&lt;/p&gt; &lt;p&gt;Most pastes are comprised of ceramic or metallic materials suspended within a proprietary binder which allows for easy application and spread as well as simple cleanup.&lt;/p&gt; &lt;p&gt;These thermal pastes can be electrically conductive or non-conductive, depending on their specific formula. Electrically conductive thermal pastes can carry current between two points, meaning that if the paste squeezes out onto other components, it can cause damage to motherboards and CPUs when you switch on the power. A single drop out of place can lead to a dead PC, so extra care is imperative.&lt;/p&gt; &lt;p&gt;Liquid metal compounds are almost always electrically conductive, so while these compounds provide better performance than their paste counterparts, they require more focus and attention during application. They are very hard to remove if you get some in the wrong place, which would fry your system.&lt;/p&gt; &lt;p&gt;In contrast, traditional thermal paste compounds are relatively simple for every experience level. Most, but not all, traditional pastes are electrically non-conductive.&lt;/p&gt; &lt;p&gt;Most cpu coolers come with their own thermal paste, so check yours before buying another one.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Add GPU advice on shopping tips.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Check that the CPU has GPU if you don&#39;t want to use an external graphic card. Otherwise the BIOS won&#39;t start.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/cpu/#installation&#34;&gt;Installation tips for CPU.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;When installing an AM4 CPU in the motherboard, rotate the CPU so that the small arrow on one of the corners of the chip matches the arrow on the corner of the motherboard socket.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;ram&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/ram/&#34;&gt;RAM&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce RAM, it&#39;s properties and how to buy it.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Random-access_memory&#34;&gt;RAM&lt;/a&gt; is a form of computer memory that can be read and changed in any order, typically used to store working data and machine code.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;power-supply-unit&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/psu/&#34;&gt;Power Supply Unit&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Power Supply Unit.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://linuxhint.com/pc-power-supply-unit/&#34;&gt;Power supply unit&lt;/a&gt; is the component of the computer that sources power from the primary source (the power coming from your wall outlet) and delivers it to its motherboard and all its components. Contrary to the common understanding, the PSU does not supply power to the computer; it instead converts the AC (Alternating Current) power from the source to the DC (Direct Current) power that the computer needs.&lt;/p&gt; &lt;p&gt;There are two types of PSU: Linear and Switch-mode. Linear power supplies have a built-in transformer that steps down the voltage from the main to a usable one for the individual parts of the computer. The transformer makes the Linear PSU bulky, heavy, and expensive. Modern computers have switched to the switch-mode power supply, using switches instead of a transformer for voltage regulation. They’re also more practical and economical to use because they’re smaller, lighter, and cheaper than linear power supplies.&lt;/p&gt; &lt;p&gt;PSU need to deliver at least the amount of power that each component requires, if it needs to deliver more, it simply won&#39;t work.&lt;/p&gt; &lt;p&gt;Another puzzling question for most consumers is, “Does a PSU supply constant wattage to the computer?” The answer is a flat No. The wattage you see on the PSUs casing or labels only indicates the maximum power it can supply to the system, theoretically. For example, by theory, a 500W PSU can supply a maximum of 500W to the computer. In reality, the PSU will draw a small portion of the power for itself and distributes power to each of the PC components according to its need. The amount of power the components need varies from 3.3V to 12V. If the total power of the components needs to add up to 250W, it would only use 250W of the 500W, giving you an overhead for additional components or future upgrades.&lt;/p&gt; &lt;p&gt;Additionally, the amount of power the PSU supplies varies during peak periods and idle times. When the components are pushed to their limits, say when a video editor maximizes the GPU for graphics-intensive tasks, it would require more power than when the computer is used for simple tasks like web-browsing. The amount of power drawn from the PSU would depend on two things; the amount of power each component requires and the tasks that each component performs.&lt;/p&gt; &lt;p&gt;I&#39;ve also added the next sections:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/psu/#power-supply-efficiency&#34;&gt;Power supply efficiency&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/psu/#power-supply-shopping-tips&#34;&gt;Power supply shopping tips&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/psu/#market-analysis&#34;&gt;Market analysis&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pedal-pc&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/pedal_pc/&#34;&gt;Pedal PC&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Pedal PC.&lt;/p&gt; &lt;p&gt;The Pedal PC idea gathers crazy projects that try to use the energy of your pedaling while you are working on your PC. The most interesting is &lt;a href=&#34;https://www.pedalpc.com/&#34;&gt;PedalPC&lt;/a&gt;, but still crazy.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;http://pedal-power.com/&#34;&gt;Pedal-Power&lt;/a&gt; is another similar project, although it looks unmaintained.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;operating-systems&#34;&gt;Operating Systems&lt;/h2&gt; &lt;h3 id=&#34;linux&#34;&gt;Linux&lt;/h3&gt; &lt;h4 id=&#34;linux-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/&#34;&gt;Linux Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#clean-up-system-space&#34;&gt;Clean up system space on debian based hosts.&lt;/a&gt;&lt;/li&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#install-one-package-from-debian-unstable&#34;&gt;Install one package from Debian unstable.&lt;/a&gt;&lt;/li&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#monitor-outgoing-traffic&#34;&gt;Monitor outgoing traffic.&lt;/a&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#clean-snap-data&#34;&gt;Clean snap data.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you&#39;re using &lt;code&gt;snap&lt;/code&gt; you can clean space by:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Reduce the number of versions kept of a package with &lt;code&gt;snap set system refresh.retain=2&lt;/code&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;Remove the old versions with &lt;code&gt;clean_snap.sh&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;ch&#34;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;#Removes old revisions of snaps&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;#CLOSE ALL SNAPS BEFORE RUNNING THIS&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-eu
&lt;span class=&#34;nv&#34;&gt;LANG&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;en_US.UTF-8&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;snap&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--all&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;awk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;/disabled/{print $1, $3}&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;snapname&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;revision&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;snap&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;remove&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$snapname&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--revision&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$revision&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#clean-journalctl-data&#34;&gt;Clean journalctl data.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Check how much space it&#39;s using: &lt;code&gt;journalctl --disk-usage&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Rotate the logs: &lt;code&gt;journalctl --rotate&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Then you have three ways to reduce the data:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Clear journal log older than X days: &lt;code&gt;journalctl --vacuum-time=2d&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Restrict logs to a certain size: &lt;code&gt;journalctl --vacuum-size=100M&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Restrict number of log files: &lt;code&gt;journactl --vacuum-files=5&lt;/code&gt;.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;The operations above will affect the logs you have right now, but it won&#39;t solve the problem in the future. To let &lt;code&gt;journalctl&lt;/code&gt; know the space you want to use open the &lt;code&gt;/etc/systemd/journald.conf&lt;/code&gt; file and set the &lt;code&gt;SystemMaxUse&lt;/code&gt; to the amount you want (for example &lt;code&gt;1000M&lt;/code&gt; for a gigabyte). Once edited restart the service with &lt;code&gt;sudo systemctl restart systemd-journald&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#set-up-docker-logs-rotation&#34;&gt;Set up docker logs rotation.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;By default, the stdout and stderr of the container are written in a JSON file located in &lt;code&gt;/var/lib/docker/containers/[container-id]/[container-id]-json.log&lt;/code&gt;. If you leave it unattended, it can take up a large amount of disk space.&lt;/p&gt; &lt;p&gt;If this JSON log file takes up a significant amount of the disk, we can purge it using the next command.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;truncate&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;logfile&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;We could setup a cronjob to purge these JSON log files regularly. But for the long term, it would be better to setup log rotation. This can be done by adding the following values in &lt;code&gt;/etc/docker/daemon.json&lt;/code&gt;.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;log-driver&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;json-file&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;log-opts&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;max-size&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;10m&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;max-file&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;10&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#clean-old-kernels&#34;&gt;Clean old kernels.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The full command is&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;dpkg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;linux-*&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;awk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;/^ii/{ print $2}&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-e&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;uname&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cut&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f1,2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;s2&#34;&gt;&#34;-&#34;&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-e&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;-9&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-E&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;(image|headers)&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;xargs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-y&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;purge
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To test what packages will it remove use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;dpkg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;linux-*&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;awk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;/^ii/{ print $2}&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-e&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;uname&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cut&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f1,2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;s2&#34;&gt;&#34;-&#34;&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-e&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;-9&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-E&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;(image|headers)&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;xargs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--dry-run&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;remove
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Remember that your running kernel can be obtained by &lt;code&gt;uname -r&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#clean-old-kernels&#34;&gt;Clean old kernels warning.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I don&#39;t recommend using this step, rely on &lt;code&gt;apt-get autoremove&lt;/code&gt;, it&#39;s safer.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#create-basic-auth-header&#34;&gt;Create Basic Auth header.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;user:password&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;base64
&lt;span class=&#34;nv&#34;&gt;dXNlcjpwYXNzd29yZA&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Without the &lt;code&gt;-n&lt;/code&gt; it won&#39;t work well.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#check-vulnerabilities-in-node.js-applications&#34;&gt;Check vulnerabilities in Node.js applications.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;With &lt;code&gt;yarn audit&lt;/code&gt; you&#39;ll see the vulnerabilities, with &lt;code&gt;yarn outdated&lt;/code&gt; you can see the packages that you need to update.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#check-vulnerabilities-in-rails-dependencies&#34;&gt;Check vulnerabilities in rails dependencies.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;gem&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;bundler-audit
&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;project_with_gem_lock
bundler-audit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#trim-silences-of-sound-files&#34;&gt;Trim silences of sound files.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To trim all silence longer than 2 seconds down to only 2 seconds long.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sox&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;.wav&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;out6.wav&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;silence&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;.1&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;%&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-1&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;.0&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;%
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Note that SoX does nothing to bits of silence shorter than 2 seconds.&lt;/p&gt; &lt;p&gt;If you encounter the &lt;code&gt;sox FAIL formats: no handler for file extension &#39;mp3&#39;&lt;/code&gt; error you&#39;ll need to install the &lt;code&gt;libsox-fmt-all&lt;/code&gt; package.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#adjust-the-replay-gain-of-many-sound-files&#34;&gt;Adjust the replay gain of many sound files.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;python-rgain
replaygain&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;*.mp3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#create-qr-code&#34;&gt;Create QR code.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;qrencode&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;qrcode.png&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Hello World!&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#git-checkout-to-main-with-master-as-a-fallback&#34;&gt;Git checkout to main with master as a fallback.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I usually use the alias &lt;code&gt;gcm&lt;/code&gt; to change to the main branch of the repository, given the change from &lt;a href=&#34;https://lyz-code.github.io/blue-book/git/#renaming-from-master-to-main&#34;&gt;main to master&lt;/a&gt; now I have some repos that use one or the other, but I still want &lt;code&gt;gcm&lt;/code&gt; to go to the correct one. The solution is to use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;alias&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;gcm&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;git checkout &#34;$(git symbolic-ref refs/remotes/origin/HEAD | cut -d&#39;&lt;/span&gt;/&lt;span class=&#34;s1&#34;&gt;&#39; -f4)&#34;&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#scan-a-physical-page-in-linux&#34;&gt;Scan a physical page in Linux.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Install &lt;code&gt;xsane&lt;/code&gt; and run it.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#get-the-output-of-docker-ps-as-a-json&#34;&gt;Get the output of &lt;code&gt;docker ps&lt;/code&gt; as a json.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To get the complete json for reference.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ps&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--format&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;{{json .}}&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;jq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To get only the required columns in the output with tab separated version&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ps&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--format&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;{{json .}}&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;jq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;[.ID, .State, .Names, .Image]&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To get &lt;a href=&#34;https://stackoverflow.com/questions/54075456/docker-ps-show-image-id-instead-of-name&#34;&gt;also the image&#39;s ID&lt;/a&gt; you can use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;inspect&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;{{json .}}&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ps&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-aq&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;jq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;[.Id, .Name, .Config.Image, .Image]&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#df-and-du-showing-different-results&#34;&gt;Df and du showing different results.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Sometimes on a linux machine you will notice that both &lt;code&gt;df&lt;/code&gt; command (display free disk space) and &lt;code&gt;du&lt;/code&gt; command (display disk usage statistics) report different output. Usually, &lt;code&gt;df&lt;/code&gt; will output a bigger disk usage than &lt;code&gt;du&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;The &lt;code&gt;du&lt;/code&gt; command estimates file space usage, and the &lt;code&gt;df&lt;/code&gt; command shows file system disk space usage.&lt;/p&gt; &lt;p&gt;There are many reasons why this could be happening:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#disk-mounted-over-data&#34;&gt;Disk mounted over data&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#used-deleted-files&#34;&gt;Used deleted files&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#clean-up-docker-data&#34;&gt;Clean up docker data.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To remove unused &lt;code&gt;docker&lt;/code&gt; data you can run &lt;code&gt;docker system prune -a&lt;/code&gt;. This will remove:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;All stopped containers&lt;/li&gt; &lt;li&gt;All networks not used by at least one container&lt;/li&gt; &lt;li&gt;All images without at least one container associated to them&lt;/li&gt; &lt;li&gt;All build cache&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Sometimes that&#39;s not enough, and your &lt;code&gt;/var/lib/docker&lt;/code&gt; directory still weights more than it should. In those cases:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Stop the &lt;code&gt;docker&lt;/code&gt; service.&lt;/li&gt; &lt;li&gt;Remove or move the data to another directory&lt;/li&gt; &lt;li&gt;Start the &lt;code&gt;docker&lt;/code&gt; service.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;In order not to loose your persisted data, you need to configure your dockers to mount the data from a directory that&#39;s not within &lt;code&gt;/var/lib/docker&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#download-ts-streams&#34;&gt;Download TS streams.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Some sites give stream content with small &lt;code&gt;.ts&lt;/code&gt; files that you can&#39;t download directly. Instead open the developer tools, reload the page and search for a request with extension &lt;code&gt;.m3u8&lt;/code&gt;, that gives you the playlist of all the chunks of &lt;code&gt;.ts&lt;/code&gt; files. Once you have that url you can use &lt;code&gt;yt-dlp&lt;/code&gt; to download it.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;qbittorrent&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/qbittorrent/&#34;&gt;qBittorrent&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce qBittorrent.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.qbittorrent.org/&#34;&gt;qBittorrent&lt;/a&gt; is &lt;a href=&#34;https://lyz-code.github.io/blue-book/torrents/&#34;&gt;my chosen&lt;/a&gt; client for &lt;a href=&#34;https://en.wikipedia.org/wiki/BitTorrent&#34;&gt;Bittorrent&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Some interesting sections added:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/qbittorrent/#Migration-from-other-client&#34;&gt;Migration from other client&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/qbittorrent/#Python-interaction&#34;&gt;Python interaction&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/qbittorrent/#Monitorization&#34;&gt;Monitorization&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/qbittorrent/#Automatic-operation&#34;&gt;Automatic operation&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;aleph&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/rtorrent/&#34;&gt;aleph&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Debug rtorrent docker problems.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce Aleph.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/alephdata/aleph&#34;&gt;Aleph&lt;/a&gt; is a tool for indexing large amounts of both documents (PDF, Word, HTML) and structured (CSV, XLS, SQL) data for easy browsing and search. It is built with investigative reporting as a primary use case. Aleph allows cross-referencing mentions of well-known entities (such as people and companies) against watchlists, e.g. from prior research or public datasets.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/#problems-accessing-redis-locally&#34;&gt;Problems accessing redis locally.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you&#39;re with the VPN connected, turn it off.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/#pdb-behaves-weird&#34;&gt;PDB behaves weird.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Sometimes you have two traces at the same time, so each time you run a PDB command it jumps from pdb trace. Quite confusing. Try to &lt;code&gt;c&lt;/code&gt; the one you don&#39;t want so that you&#39;re left with the one you want. Or put the &lt;code&gt;pdb&lt;/code&gt; trace in a conditional that only matches one of both threads.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;anki&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/anki/&#34;&gt;Anki&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Anki.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://apps.ankiweb.net/&#34;&gt;Anki&lt;/a&gt; is a program which makes remembering things easy. Because it&#39;s a lot more efficient than traditional study methods, you can either greatly decrease your time spent studying, or greatly increase the amount you learn.&lt;/p&gt; &lt;p&gt;Anyone who needs to remember things in their daily life can benefit from Anki. Since it is content-agnostic and supports images, audio, videos and scientific markup (via LaTeX), the possibilities are endless.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/anki/#interacting-with-python&#34;&gt;Interacting with python.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Although there are some python libraries:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/kerrickstaley/genanki&#34;&gt;genanki&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://pypi.org/project/py-anki/&#34;&gt;py-anki&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;I think the best way is to use &lt;a href=&#34;https://foosoft.net/projects/anki-connect/&#34;&gt;AnkiConnect&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The installation process is similar to other Anki plugins and can be accomplished in three steps:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Open the &lt;em&gt;Install Add-on&lt;/em&gt; dialog by selecting &lt;em&gt;Tools | Add-ons | Get Add-ons...&lt;/em&gt; in Anki.&lt;/li&gt; &lt;li&gt;Input &lt;code&gt;2055492159&lt;/code&gt; into the text box labeled &lt;em&gt;Code&lt;/em&gt; and press the &lt;em&gt;OK&lt;/em&gt; button to proceed.&lt;/li&gt; &lt;li&gt;Restart Anki when prompted to do so in order to complete the installation of Anki-Connect.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Anki must be kept running in the background in order for other applications to be able to use Anki-Connect. You can verify that Anki-Connect is running at any time by accessing &lt;code&gt;localhost:8765&lt;/code&gt; in your browser. If the server is running, you will see the message Anki-Connect displayed in your browser window.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/anki/#usage&#34;&gt;Use anki connect with python.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;ferdium&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/ferdium/&#34;&gt;ferdium&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce ferdium.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://ferdium.org&#34;&gt;Ferdium&lt;/a&gt; is a desktop application to have all your services in one place. It&#39;s similar to Rambox, Franz or Ferdi only that it&#39;s maintained by the community and respects your privacy.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;finnix&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/finnix/&#34;&gt;finnix&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce finnix.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.finnix.org/&#34;&gt;Finnix&lt;/a&gt; is a live Linux distribution specialized in the recovery, maintenance, testing of systems.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;github-cli&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gh/&#34;&gt;Github cli&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gh/#trigger-a-workflow-run&#34;&gt;Trigger a workflow run.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To manually trigger a workflow you need to first configure it to allow &lt;a href=&#34;https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_dispatch&#34;&gt;&lt;code&gt;workflow_dispatch&lt;/code&gt; events&lt;/a&gt;.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;workflow_dispatch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then you can trigger the workflow with &lt;code&gt;gh workflow run {{ workflow_name }}&lt;/code&gt;, where you can get the &lt;code&gt;workflow_name&lt;/code&gt; with &lt;code&gt;gh workflow list&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;goaccess&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/goaccess/&#34;&gt;goaccess&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce goaccess.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://goaccess.io/&#34;&gt;goaccess&lt;/a&gt; is a fast terminal-based log analyzer.&lt;/p&gt; &lt;p&gt;Its core idea is to quickly analyze and view web server statistics in real time without needing to use your browser (great if you want to do a quick analysis of your access log via SSH, or if you simply love working in the terminal).&lt;/p&gt; &lt;p&gt;While the terminal output is the default output, it has the capability to generate a complete, self-contained real-time HTML report (great for analytics, monitoring and data visualization), as well as a JSON, and CSV report.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;i3wm&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/i3wm/&#34;&gt;i3wm&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce i3wm.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://i3wm.org/&#34;&gt;i3&lt;/a&gt; is a tiling window manager.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/i3wm/#layout-saving&#34;&gt;Layout saving.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Layout saving/restoring allows you to load a JSON layout file so that you can have a base layout to start working with after powering on your computer.&lt;/p&gt; &lt;p&gt;First of all arrange the windows in the workspace, then you can save the layout of either a single workspace or an entire output:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;i3-save-tree&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--workspace&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;1: terminal&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;~/.i3/workspace-1.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You need to open the created file and remove the comments that match the desired windows under the &lt;code&gt;swallows&lt;/code&gt; keys, so transform the next snippet:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;...&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;swallows&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//  &#34;class&#34;: &#34;^URxvt$&#34;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//  &#34;instance&#34;: &#34;^irssi$&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Into:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;...&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;swallows&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;class&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;^URxvt$&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;instance&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;^irssi$&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Once is ready close all the windows of the workspace you want to restore (moving them away is not enough!).&lt;/p&gt; &lt;p&gt;Then on a terminal you can restore the layout with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;i3-msg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;workspace &#34;1: terminal&#34;; append_layout ~/.i3/workspace-1.json&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;div class=&#34;admonition warning&#34;&gt; &lt;p class=&#34;admonition-title&#34;&gt;It&#39;s important that you don&#39;t use a relative path&lt;/p&gt; &lt;p&gt;Even if you&#39;re in &lt;code&gt;~/.i3/&lt;/code&gt; you have to use &lt;code&gt;i3-msg append_layout ~/.i3/workspace-1.json&lt;/code&gt;.&lt;/p&gt; &lt;/div&gt; &lt;p&gt;This command will create some fake windows (called placeholders) with the layout you had before, &lt;code&gt;i3&lt;/code&gt; will then wait for you to create the windows that match the selection criteria. Once they are, it will put them in their respective placeholders.&lt;/p&gt; &lt;p&gt;If you wish to create the layouts at startup you can add the next snippet to your i3 config.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;exec --no-startup-id &#34;i3-msg &#39;workspace \&#34;1: terminal\&#34;; append_layout ~/.i3/workspace-1.json&#39;&#34;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;ffmpeg&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/ffmpeg/&#34;&gt;ffmpeg&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ffmpeg/#convert-vob-to-mkv&#34;&gt;Convert VOB to mkv.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Unify your VOBs &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;*.VOB&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output.vob
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Identify the streams&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ffmpeg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-analyzeduration&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;100M&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-probesize&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;100M&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output.vob
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Select the streams that you are interested in, imagine that is 1, 3, 4, 5 and 6.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Encoding&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ffmpeg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-analyzeduration&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;100M&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-probesize&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;100M&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output.vob&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-map&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;:1&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-map&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;:3&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-map&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;:4&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-map&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;:5&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-map&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;:6&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-metadata:s:a:0&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;language&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;ita&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-metadata:s:a:0&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Italian stereo&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-metadata:s:a:1&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;language&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;eng&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-metadata:s:a:1&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;English stereo&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-metadata:s:s:0&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;language&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;ita&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-metadata:s:s:0&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Italian&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-metadata:s:s:1&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;language&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;eng&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-metadata:s:s:1&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;English&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-codec:v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libx264&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-crf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-codec:a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libmp3lame&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-qscale:a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;-codec:s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;copy&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;output.mkv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;khal&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/khal/&#34;&gt;Khal&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce khal.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://khal.readthedocs.io/en/latest/index.html&#34;&gt;&lt;code&gt;khal&lt;/code&gt;&lt;/a&gt; is a standards based Python CLI (console) calendar program, able to synchronize with &lt;a href=&#34;http://en.wikipedia.org/wiki/CalDAV&#34;&gt;CalDAV&lt;/a&gt; servers through &lt;a href=&#34;https://lyz-code.github.io/blue-book/vdirsyncer/&#34;&gt;&lt;code&gt;vdirsyncer&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Features:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Can read and write events/icalendars to vdir, so &lt;a href=&#34;https://lyz-code.github.io/blue-book/vdirsyncer/&#34;&gt;&lt;code&gt;vdirsyncer&lt;/code&gt;&lt;/a&gt; can be used to synchronize calendars with a variety of other programs, for example CalDAV servers.&lt;/li&gt; &lt;li&gt;Fast and easy way to add new events&lt;/li&gt; &lt;li&gt;&lt;code&gt;ikhal&lt;/code&gt; (interactive &lt;code&gt;khal&lt;/code&gt;) lets you browse and edit calendars and events.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Limitations:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Only rudimentary support for creating and editing recursion rules&lt;/li&gt; &lt;li&gt;You cannot edit the timezones of events&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/khal/#edit-the-events-in-a-more-pleasant-way&#34;&gt;Edit the events in a more pleasant way.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The &lt;code&gt;ikhal&lt;/code&gt; event editor is not comfortable for me. I usually only change the title or the start date and in the default interface you need to press many keystrokes to make it happen.&lt;/p&gt; &lt;p&gt;A patch solution is to pass a custom script on the &lt;code&gt;EDITOR&lt;/code&gt; environmental variable. Assuming you have &lt;a href=&#34;https://lyz-code.github.io/blue-book/questionary/&#34;&gt;&lt;code&gt;questionary&lt;/code&gt;&lt;/a&gt; and &lt;a href=&#34;https://lyz-code.github.io/blue-book/ics/&#34;&gt;&lt;code&gt;ics&lt;/code&gt;&lt;/a&gt; installed you can save the next snippet into an &lt;code&gt;edit_event&lt;/code&gt; file in your &lt;code&gt;PATH&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Edit an ics calendar event.&#34;&#34;&#34;&lt;/span&gt;

&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;sys&lt;/span&gt;

&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;questionary&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;ics&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Calendar&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;file&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;r&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;calendar&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Calendar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fd&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;event&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;calendar&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timeline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;questionary&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Title: &#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ask&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;start&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;questionary&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;Start: &#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;begin&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hour&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zfill&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;begin&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;minute&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zfill&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ask&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;begin&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;begin&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;replace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;hour&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;split&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;:&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;minute&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;split&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;:&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;w&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;fd&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;writelines&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;calendar&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;serialize_iter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Now if you open &lt;code&gt;ikhal&lt;/code&gt; as &lt;code&gt;EDITOR=edit_event ikhal&lt;/code&gt;, whenever you edit one event you&#39;ll get a better interface. Add to your &lt;code&gt;.zshrc&lt;/code&gt; or &lt;code&gt;.bashrc&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;alias&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ikhal&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;EDITOR=edit_event ikhal&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The default keybinding for the edition is not very comfortable either, add the next snippet on your config:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[keybindings]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;external_edit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;e&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;meta e&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;luks&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/luks/luks/&#34;&gt;LUKS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/luks/luks/#break-a-luks-password&#34;&gt;Break a luks password.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can use &lt;a href=&#34;https://github.com/glv2/bruteforce-luks&#34;&gt;&lt;code&gt;bruteforce-luks&lt;/code&gt;&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pipx&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/pipx/&#34;&gt;Pipx&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce pipx.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://pypa.github.io/pipx/&#34;&gt;Pipx&lt;/a&gt; is a command line tool to install and run Python applications in isolated environments.&lt;/p&gt; &lt;p&gt;Very useful not to pollute your user or device python environments.&lt;/p&gt; &lt;p&gt;Install it with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pipx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;profanity&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/profanity/&#34;&gt;Profanity&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce profanity.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://profanity-im.github.io/&#34;&gt;profanity&lt;/a&gt; is a console based XMPP client written in C using ncurses and libstrophe, inspired by Irssi.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;libreelec&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/libreelec/&#34;&gt;Libreelec&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce LibreElec.&lt;/p&gt; &lt;p&gt;LibreElec is the lightweight distribution to run Kodi&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;torrents&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/torrents/&#34;&gt;Torrents&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Compare the different torrent clients.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/BitTorrent&#34;&gt;BitTorrent&lt;/a&gt; is a communication protocol for peer-to-peer file sharing (P2P), which enables users to distribute data and electronic files over the Internet in a decentralized manner.&lt;/p&gt; &lt;p&gt;Each of us seeks something different for a torrent client, thus there is a wide set of software, you just need to find the one that&#39;s best for you. In my case I&#39;m searching for a client that:&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Scales well for many torrents&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Is robust&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Is maintained&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Is popular&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Is supported by the private trackers: Some torrent clients are banned by the tracker because they don&#39;t report correctly to the tracker when canceling/finishing a torrent session. If you use them then a few MB may not be counted towards the stats near the end, and torrents may still be listed in your profile for some time after you have closed the client. Each tracker has their list of allowed clients. Make sure to check them.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Also, clients in alpha or beta versions should be avoided.&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Can be easily monitored&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Has a Python library or an API to interact with&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Has clear and enough logs&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Has RSS support&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Has a pleasant UI&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Supports categories&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Can unpack content once it&#39;s downloaded&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;No ads&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Easy to use behind a VPN with IP leakage protection.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Easy to deploy&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;I don&#39;t need other features such as:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Preview content&lt;/li&gt; &lt;li&gt;Search in the torrent client&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The winner has been &lt;a href=&#34;https://lyz-code.github.io/blue-book/qbittorrent/&#34;&gt;qBittorrent&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;vdirsyncer&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vdirsyncer/&#34;&gt;vdirsyncer&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce vdirsyncer.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://vdirsyncer.pimutils.org/en/stable/&#34;&gt;vdirsyncer&lt;/a&gt; is a Python command-line tool for synchronizing calendars and addressbooks between a variety of servers and the local filesystem. The most popular usecase is to synchronize a server with a local folder and use a set of other programs such as &lt;a href=&#34;https://lyz-code.github.io/blue-book/khal/&#34;&gt;&lt;code&gt;khal&lt;/code&gt;&lt;/a&gt; to change the local events and contacts. Vdirsyncer can then synchronize those changes back to the server.&lt;/p&gt; &lt;p&gt;However, &lt;code&gt;vdirsyncer&lt;/code&gt; is not limited to synchronizing between clients and servers. It can also be used to synchronize calendars and/or addressbooks between two servers directly.&lt;/p&gt; &lt;p&gt;It aims to be for calendars and contacts what OfflineIMAP is for emails.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;vim&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/&#34;&gt;Vim&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/#delete-a-file-inside-vim&#34;&gt;Delete a file inside vim.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;call&lt;/span&gt; delete&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;expand&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;%&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;bdelete&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;vscodium&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vscodium/&#34;&gt;VSCodium&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce VSCodium.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/VSCodium/vscodium&#34;&gt;VSCodium&lt;/a&gt; are binary releases of VS Code without MS branding/telemetry/licensing.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;wallabag&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/wallabag/&#34;&gt;Wallabag&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce wallabag.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://doc.wallabag.org&#34;&gt;Wallabag&lt;/a&gt; is a self-hosted read-it-later application: it saves a web page by keeping content only. Elements like navigation or ads are deleted.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;wireshark&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/wireshark/&#34;&gt;Wireshark&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Wireshark, it&#39;s installation and basic usage.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.wireshark.org/&#34;&gt;Wireshark&lt;/a&gt; is the world’s foremost and widely-used network protocol analyzer. It lets you see what’s happening on your network at a microscopic level and is the de facto (and often de jure) standard across many commercial and non-profit enterprises, government agencies, and educational institutions.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;android&#34;&gt;Android&lt;/h3&gt; &lt;h4 id=&#34;android-tips&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/android_tips/&#34;&gt;Android Tips&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/android_tips/#extend-the-life-of-your-battery&#34;&gt;Extend the life of your battery.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://accubattery.zendesk.com/hc/en-us/articles/210224725-Charging-research-and-methodology&#34;&gt;Research&lt;/a&gt; has shown that keeping your battery charged between 0% and 80% can make your battery&#39;s lifespan last 2x longer than when you use a full battery cycle from 0-100%.&lt;/p&gt; &lt;p&gt;As a non root user you can &lt;a href=&#34;https://www.getdroidtips.com/custom-battery-charge-limit-android/&#34;&gt;install Accubattery&lt;/a&gt; (not in F-droid :( ) to get an alarm when the battery reaches 80% so that you can manually unplug it. Instead of leaving the mobile charge in the night and stay connected at 100% a lot of hours until you unplug, charge it throughout the day.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;grapheneos&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/grapheneos/&#34;&gt;GrapheneOS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce GrapheneOS.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://grapheneos.org/&#34;&gt;GrapheneOS&lt;/a&gt; is a private and secure mobile operating system with Android app compatibility. Developed as a non-profit open source project.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce GrapheneOS.&lt;/p&gt; &lt;p&gt;GrapheneOS is a private and secure mobile operating system with great functionality and usability. It starts from the strong baseline of the Android Open Source Project (AOSP) and takes great care to avoid increasing attack surface or hurting the strong security model. GrapheneOS makes substantial improvements to both privacy and security through many carefully designed features built to function against real adversaries. The project cares a lot about usability and app compatibility so those are taken into account for all of our features.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/grapheneos/#installation&#34;&gt;Installation.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I was not able to follow the &lt;a href=&#34;https://grapheneos.org/install/web&#34;&gt;web&lt;/a&gt; instructions so I had to follow the &lt;a href=&#34;https://grapheneos.org/install/cli&#34;&gt;cli&lt;/a&gt; ones.&lt;/p&gt; &lt;p&gt;Whenever I run a &lt;code&gt;fastboot&lt;/code&gt; command it got stuck in &lt;code&gt;&amp;lt; waiting for devices &amp;gt;&lt;/code&gt;, so I added the next rules on the &lt;code&gt;udev&lt;/code&gt; configuration at &lt;code&gt;/etc/udev/rules.d/51-android.rules&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;SUBSYSTEM==&#34;usb&#34;, ATTR{idVendor}==&#34;18d1&#34;, ATTR{idProduct}==&#34;4ee7&#34;, MODE=&#34;0600&#34;, OWNER=&#34;myuser&#34;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The &lt;code&gt;idProduct&lt;/code&gt; and &lt;code&gt;idVendor&lt;/code&gt; were deduced from &lt;code&gt;lsusb&lt;/code&gt;. Then after a restart everything worked fine.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;arts&#34;&gt;Arts&lt;/h2&gt; &lt;h3 id=&#34;writing&#34;&gt;Writing&lt;/h3&gt; &lt;h4 id=&#34;forking-this-garden&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/forking_this_wiki/&#34;&gt;Forking this garden&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Update forking instructions.&lt;/p&gt; &lt;p&gt;I recommend against forking the repository via Github. If you do that, you&#39;ll have all the history of my repository, which will make your repository more heavy than it should (as I have a lot of images), and it will make it hard for me to make pull requests to your digital garden.&lt;/p&gt; &lt;p&gt;Furthermore, you&#39;ll always see a message in your repo similar to &lt;code&gt;This branch is 909 commits ahead, 1030 commits behind lyz-code:master.&lt;/code&gt; like you can see in &lt;a href=&#34;https://github.com/m0wer/memento&#34;&gt;this fork&lt;/a&gt;. Also if you don&#39;t want to keep all the content I&#39;ve made so far and want to start from scratch then the only thing that is useful for you is the skeleton I&#39;ve made, and I don&#39;t need any attribution or credit for that :P.&lt;/p&gt; &lt;p&gt;If on the other hand you do want to keep all my content, then wouldn&#39;t it be better to just make contributions to this repository instead?&lt;/p&gt; &lt;p&gt;Therefore the best way to give credit and attribution is by building your garden (the more we are writing the merrier :) ), and then if you want to spread the word that my garden exists within your content then that would be awesome.&lt;/p&gt; &lt;p&gt;If you end up building your own, remember to add yourself to the &lt;a href=&#34;https://github.com/lyz-code/best-of-digital-gardens&#34;&gt;digital garden&#39;s list&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;cooking&#34;&gt;Cooking&lt;/h3&gt; &lt;h4 id=&#34;cooking-software&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/cooking_software/&#34;&gt;Cooking software&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Analysis of existing recipe manager software.&lt;/p&gt; &lt;p&gt;List the expected features from the recipe manager and add links of the software found after an analysis of the state of the art, it&#39;s still a work in progress&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Finish the state of the art analysis.&lt;/p&gt; &lt;p&gt;Review Cooklang, KookBook, RecipeSage, Mealie and Chowdown&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;aerial-silk&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aerial_silk/&#34;&gt;Aerial Silk&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Aerial Silk, some warmups and some figures.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Aerial_silk&#34;&gt;Aerial Silk&lt;/a&gt; is a type of performance in which one or more artists perform aerial acrobatics while hanging from a fabric. The fabric may be hung as two pieces, or a single piece, folded to make a loop, classified as hammock silks. Performers climb the suspended fabric without the use of safety lines and rely only on their training and skill to ensure safety. They use the fabric to wrap, suspend, drop, swing, and spiral their bodies into and out of various positions. Aerial silks may be used to fly through the air, striking poses and figures while flying. Some performers use dried or spray rosin on their hands and feet to increase the friction and grip on the fabric.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;meditation&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/meditation/&#34;&gt;Meditation&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/meditation/#references&#34;&gt;Add NonCompete recommendations.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://invidious.osi.kr/watch?v=xSHXHHblin0&#34;&gt;His meditation for anti-capitalists video&lt;/a&gt;&lt;/li&gt; &lt;li&gt;The &lt;a href=&#34;https://www.goodreads.com/en/book/show/25942786-the-mind-illuminated&#34;&gt;The Mind Illuminated: A Complete Meditation Guide Integrating Buddhist Wisdom and Brain Science by Culadasa (John Yates)&lt;/a&gt; book.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;maker&#34;&gt;Maker&lt;/h3&gt; &lt;h4 id=&#34;redox&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/redox/&#34;&gt;Redox&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Redox.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/mattdibi/redox-keyboard&#34;&gt;Redox&lt;/a&gt; is an awesome Do It Yourself mechanical keyboard&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Installation instructions.&lt;/p&gt; &lt;p&gt;First flash:&lt;/p&gt; &lt;p&gt;Download the hex from the via website&lt;/p&gt; &lt;p&gt;Try to flash it many times reseting the promicros.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;avrdude&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-b&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;57600&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;m32u4&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-P&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/ttyACM0&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;avr109&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-D&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-U&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;flash:w:redox_rev1_base_via.hex
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Once the write has finished install via:&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/the-via/releases/releases&#34;&gt;https://github.com/the-via/releases/releases&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Reboot the computer&lt;/p&gt; &lt;p&gt;Launch it with &lt;code&gt;via-nativia&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;video-gaming&#34;&gt;Video Gaming&lt;/h3&gt; &lt;h4 id=&#34;king-arthur-gold&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/kag/&#34;&gt;King Arthur Gold&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce King Arthur Gold.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://kag2d.com/en/&#34;&gt;King Arthur Gold&lt;/a&gt;, also known as KAG, is a free Medieval Build n&#39;Kill Multiplayer Game with Destructible Environments.&lt;/p&gt; &lt;p&gt;Construct freeform forts as a medieval Builder, fight in sword duels as a Knight or snipe with your bow as an Archer. KAG blends the cooperative aspects of Lost Vikings, mashes them with the full destructibility of Worms and the visual style and action of Metal Slug, brought to you by the creators of Soldat.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/kag/#builder-guides&#34;&gt;Builder guides.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://deynarde.github.io/kag-builder-guide&#34;&gt;Turtlebutt and Bunnie&lt;/a&gt; guide is awesome.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;age-of-empires&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/age_of_empires/&#34;&gt;Age of Empires&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the Age of Empires videogame.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/age_of_empires/#basic-opening&#34;&gt;How to do the basic opening&lt;/a&gt;: What to do when to pass to the feudal age in 8 minutes 30 seconds&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/age_of_empires/#Micromanagements&#34;&gt;How to micromanage&lt;/a&gt; different processes such as sheep, deer, boar hunting, house building, lumberjacking&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;board-gaming&#34;&gt;Board Gaming&lt;/h3&gt; &lt;h4 id=&#34;regicide&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/regicide/&#34;&gt;Regicide&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/regicide/#player-modifiers&#34;&gt;Player modifiers extension.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;At the start of the game players can decide their suit, they will get a bonus on the played cards of their suit, and a penalization on the opposite suit. The opposite suits are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;♠ opposite of ♥&lt;/li&gt; &lt;li&gt;♣ opposite of ♦&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The bonus depends on the level of the enemy being:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;J: +1 or -1&lt;/li&gt; &lt;li&gt;Q: +2 or -2&lt;/li&gt; &lt;li&gt;K: +3 or -3&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;sudokus&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/sudokus/&#34;&gt;Sudokus&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the sudoku game.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Sudoku&#34;&gt;Sudoku&lt;/a&gt; is a logic-based, combinatorial number-placement puzzle. In classic Sudoku, the objective is to fill a 9 × 9 grid with digits so that each column, each row, and each of the nine 3 × 3 subgrids that compose the grid (also called &#34;boxes&#34;, &#34;blocks&#34;, or &#34;regions&#34;) contain all of the digits from 1 to 9. The puzzle setter provides a partially completed grid, which for a well-posed puzzle has a single solution.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;book-binding&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/book_binding/&#34;&gt;Book Binding&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce book binding.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Bookbinding&#34;&gt;Book binding&lt;/a&gt; is the process of physically assembling a book of codex format from an ordered stack of paper sheets that are folded together into sections called signatures or sometimes left as a stack of individual sheets. Several signatures are then bound together along one edge with a thick needle and sturdy thread.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;science&#34;&gt;Science&lt;/h2&gt; &lt;h3 id=&#34;data-analysis&#34;&gt;Data Analysis&lt;/h3&gt; &lt;h4 id=&#34;recommender-systems&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/data_analysis/recommender_systems/recommender_systems/&#34;&gt;Recommender Systems&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/data_analysis/recommender_systems/recommender_systems/#interesting-resources&#34;&gt;Add book recommender.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://bookwyrm.social&#34;&gt;Bookwyrm&lt;/a&gt; looks to be a promising source to build book recommender systems.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;other&#34;&gt;Other&lt;/h2&gt; &lt;ul&gt; &lt;li&gt;Reorganization: Reorder the blue book navigation panel.&lt;/li&gt; &lt;li&gt;New: Sum up all the VueJS documentation.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Troubleshoot Failed to resolve component: X.&lt;/p&gt; &lt;p&gt;If you&#39;ve already imported the component with &lt;code&gt;import X from &#39;./X.vue&lt;/code&gt; you may have forgotten to add the component to the &lt;code&gt;components&lt;/code&gt; property of the module:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Inbox&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;components&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;X&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Reorganization: Reorder the programming languages under a Languages section.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Bear with me or Bare with me.&lt;/p&gt; &lt;p&gt;&#34;Bear with me&#34; is the correct form.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Correct argument to use pipes in terminals.&lt;/p&gt; &lt;p&gt;You don&#39;t use &lt;code&gt;check=True&lt;/code&gt; but &lt;code&gt;shell=True&lt;/code&gt;, thanks &lt;a href=&#34;https://github.com/pawamoy&#34;&gt;pawamoy&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Update http versions to &lt;code&gt;HTTP/2.0&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;It seems that the correct protocol is HTTP/2.0 now: &lt;a href=&#34;https://github.com/prometheus/blackbox_exporter/issues/658&#34;&gt;https://github.com/prometheus/blackbox_exporter/issues/658&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce the Alder tree.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34; &#34; src=&#34;../../img/Alder-3.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Alders are trees comprising the genus Alnus in the birch family Betulaceae (like the &lt;a href=&#34;#birch&#34;&gt;birch&lt;/a&gt;). The genus parts are &#34;al&#34; which means &#34;close by&#34; and &#34;lan&#34; which means &#34;side of the river&#34;, so they are trees that grow close to rivers or creeks.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Give more details of the beech tree.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34; &#34; src=&#34;../../img/beech-4.jpg&#34;/&gt; The leaves of beech trees are elliptic, a little pointy at the end, flat, and with a short petiole. They are big and wide leaves ranging from 4-9 cm long. Very abundant, they have a light green colour with a darker tone and glossy on the upper side.&lt;/p&gt; &lt;p&gt;The fruit is a small, sharply three-angled nut 10-15 mm long, borne singly or in pairs in soft-spined husks 1.5-2.5 cm long, known as cupules. The husk can have a variety of spine- to scale-like appendages, the character of which is, in addition to leaf shape, one of the primary ways beeches are differentiated. The nuts are edible, though bitter (though not nearly as bitter as acorns) with a high tannin content, and are called beechnuts or beechmast.&lt;/p&gt; &lt;p&gt;They are big trees easily going between 30 and 45 meters. It looks very different if its isolated or being part of a forest. The first one the branches grow from the middle of the trunk and are horizontal, in the second, the branches go up and start over the half of the trunk. The principal root is very powerful, with very strong secondary roots, developing lateral superficial roots.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34; &#34; src=&#34;../../img/beech-bark.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;The trunk is right with a grayish-cinder bark, smooth until it&#39;s old, usually covered by moss an lichen. Smaller branches are zigzagging with reddish-brown pointy buds.&lt;/p&gt; &lt;p&gt;The canopy is big, dense, rounded and semi spheric, giving a lot of shadow.&lt;/p&gt; &lt;p&gt;It grows slow in the first years, being the most active between the tenth and twelve year, reaching it&#39;s maximum height when it&#39;s twenty five, although it lives around three hundred years.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Give more details of the birch tree.&lt;/p&gt; &lt;p&gt;The simple leaves are rhomboidal, between 3 and 6 cm, singly or doubly serrate except at the base, feather-veined, petiolate and stipulate. Although they are alternate, many leaves spawn from each side of the branch, making some think that they are not alternate. They often appear in pairs, but these pairs are really borne on spur-like, two-leaved, lateral branchlets.&lt;/p&gt; &lt;p&gt;The canopy is rounded and irregular giving few shadow.&lt;/p&gt; &lt;p&gt;The fruit is a small samara, although the wings may be obscure in some species. They differ from the alders in that the female catkins are not woody and disintegrate at maturity, falling apart to release the seeds, unlike the woody, cone-like female alder catkins.&lt;/p&gt; &lt;p&gt;The bark of all birches is characteristically smooth and white, although in older ones the lower part is usually cracked and takes blackish brown colours. It&#39;s marked with long, horizontal lenticels, and often separates into thin, papery plates, especially upon the paper birch.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: How to tell apart the different trees.&lt;/p&gt; &lt;p&gt;Alder vs Beech:&lt;/p&gt; &lt;table&gt; &lt;thead&gt; &lt;tr&gt; &lt;th&gt;Property&lt;/th&gt; &lt;th&gt;Beech&lt;/th&gt; &lt;th&gt;Alder&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Leaf border&lt;/td&gt; &lt;td&gt;flat&lt;/td&gt; &lt;td&gt;sparsely toothed&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Leaf form&lt;/td&gt; &lt;td&gt;elliptic&lt;/td&gt; &lt;td&gt;rounded&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Same colour both sides&lt;/td&gt; &lt;td&gt;no (darker and glossy up)&lt;/td&gt; &lt;td&gt;yes&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Sticky leafs&lt;/td&gt; &lt;td&gt;no&lt;/td&gt; &lt;td&gt;yes&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Size&lt;/td&gt; &lt;td&gt;30-45m&lt;/td&gt; &lt;td&gt;10-12m (in Europe)&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Knots on the roots with fungi&lt;/td&gt; &lt;td&gt;no&lt;/td&gt; &lt;td&gt;yes&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Where they grow&lt;/td&gt; &lt;td&gt;everywhere&lt;/td&gt; &lt;td&gt;close to rivers or creeks&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Alder vs Birch:&lt;/p&gt; &lt;table&gt; &lt;thead&gt; &lt;tr&gt; &lt;th&gt;Property&lt;/th&gt; &lt;th&gt;Birch&lt;/th&gt; &lt;th&gt;Alder&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Leaf border&lt;/td&gt; &lt;td&gt;heavy toothed&lt;/td&gt; &lt;td&gt;sparsely toothed&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Leaf form&lt;/td&gt; &lt;td&gt;rhomboidal&lt;/td&gt; &lt;td&gt;rounded&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Sticky leafs&lt;/td&gt; &lt;td&gt;no&lt;/td&gt; &lt;td&gt;yes&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Where they grow&lt;/td&gt; &lt;td&gt;very close to each other&lt;/td&gt; &lt;td&gt;close to rivers or creeks&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Beech vs Birch:&lt;/p&gt; &lt;table&gt; &lt;thead&gt; &lt;tr&gt; &lt;th&gt;Property&lt;/th&gt; &lt;th&gt;Beech&lt;/th&gt; &lt;th&gt;Birch&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Leaf border&lt;/td&gt; &lt;td&gt;flat&lt;/td&gt; &lt;td&gt;heavy toothed&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Leaf form&lt;/td&gt; &lt;td&gt;elliptic&lt;/td&gt; &lt;td&gt;rhomboidal&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Size&lt;/td&gt; &lt;td&gt;30-45m&lt;/td&gt; &lt;td&gt;10-15m (in Europe)&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Same colour both sides&lt;/td&gt; &lt;td&gt;no (darker and glossy up)&lt;/td&gt; &lt;td&gt;yes&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Where they grow&lt;/td&gt; &lt;td&gt;everywhere&lt;/td&gt; &lt;td&gt;very close to each other&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;/li&gt; &lt;/ul&gt; &lt;aside class=&#34;md-source-file&#34;&gt; &lt;span class=&#34;md-source-file__fact&#34;&gt; &lt;span class=&#34;md-icon&#34; title=&#34;Last update&#34;&gt; &lt;svg viewbox=&#34;0 0 24 24&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z&#34;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt; &lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago&#34; title=&#34;November 27, 2024 15:36:58 UTC&#34;&gt;&lt;span class=&#34;timeago&#34; datetime=&#34;2024-11-27T15:36:58+00:00&#34; locale=&#34;en&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date&#34; title=&#34;November 27, 2024 15:36:58 UTC&#34;&gt;2024-11-27&lt;/span&gt; &lt;/span&gt; &lt;/aside&gt; &lt;/article&gt;</description>
      <link>https://lyz-code.github.io/blue-book/newsletter/2022/</link>
      <pubDate>2024-11-27 15:36:58+00:00</pubDate>
      <source url="https://lyz-code.github.io/blue-book/yearly.xml">The Blue Book</source>
      <guid isPermaLink="true">https://lyz-code.github.io/blue-book/newsletter/2022/</guid>
      
    </item>
    
    <item><title>2021</title>
      <author>Lyz</author>
      <description>&lt;article class=&#34;md-content__inner md-typeset&#34;&gt;  &lt;h2 id=&#34;introduction&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/&#34;&gt;Introduction&lt;/a&gt;&lt;/h2&gt; &lt;ul&gt; &lt;li&gt;New: Simplify the landing page text.&lt;/li&gt; &lt;li&gt;Reorganization: Merge the Meta article into the index.&lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;projects&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/&#34;&gt;Projects&lt;/a&gt;&lt;/h2&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Improvement: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#mkdocs-newsletter&#34;&gt;Add mkdocs-newsletter as a dormant plant.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;MkDocs plugin to show the changes of documentation repositories in a user friendly format, at the same time that it&#39;s easy for the authors to maintain.&lt;/p&gt; &lt;p&gt;It creates daily, weekly, monthly and yearly newsletter articles with the changes of each period. Those pages, stored under the &lt;code&gt;Newsletters&lt;/code&gt; section, are filled with the changes extracted from the commit messages of the git history. The changes are grouped by categories, subcategories and then by file using the order of the site&#39;s navigation structure. RSS feeds are also created for each newsletter type, so it&#39;s easy for people to keep updated with the evolution of the site.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Reorganization: Update and reorganize projects.&lt;/p&gt; &lt;p&gt;Following the &lt;a href=&#34;https://lyz-code.github.io/blue-book/digital_garden/&#34;&gt;digital garden&lt;/a&gt; metaphor&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Reorganization: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#seeds&#34;&gt;Merge the wish_list article into the projects.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt;New: Add seed to follow the updates of software.&lt;/li&gt; &lt;li&gt;New: Add seed to automatically update the dockers of maintained services.&lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Explain the updates on the repository-orm project.&lt;/p&gt; &lt;p&gt;In the latest version &lt;code&gt;0.2.0&lt;/code&gt;, we added:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Support for the &lt;a href=&#34;https://lyz-code.github.io/repository-orm/tinydb_repository/&#34;&gt;TinyDB repository&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;Support for regular expressions in the &lt;code&gt;search&lt;/code&gt; method.&lt;/li&gt; &lt;li&gt;Easier repository loading with &lt;code&gt;load_repository&lt;/code&gt; function.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Add a link to the meilisearch &lt;a href=&#34;https://blog.meilisearch.com/&#34;&gt;blog&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Create the quantified self project.&lt;/p&gt; &lt;p&gt;With links to the two starting points &lt;a href=&#34;https://beepb00p.xyz/hpi.html&#34;&gt;HPI&lt;/a&gt; and &lt;a href=&#34;https://github.com/bionic-dev/bionic&#34;&gt;bionic&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#automate-email-management&#34;&gt;Sketch how to automate repetitive tasks prompted by email events.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Most of the emails I receive require repetitive actions that can be automated, I&#39;ve stumbled upon &lt;a href=&#34;https://notmuchmail.org/&#34;&gt;notmuchmail&lt;/a&gt;, which looks very promising. A friend suggested to use &lt;a href=&#34;https://afew.readthedocs.io/en/latest/&#34;&gt;afew&lt;/a&gt; for tagging, and I&#39;d probably use &lt;a href=&#34;https://github.com/pazz/alot&#34;&gt;alot&lt;/a&gt; to interact with the system (and finally be able to use email from the cli).&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#quantified-self&#34;&gt;Add interesting interface.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;For the interface &lt;a href=&#34;https://github.com/adri/memex&#34;&gt;adri&#39;s memex&lt;/a&gt; looks awesome! It&#39;s inspired in the Andrew Louis &lt;a href=&#34;https://www.youtube.com/watch?v=DFWxvQn4cf8&amp;amp;t=1616s&#34;&gt;talk Building a Memex&lt;/a&gt; whose &lt;a href=&#34;https://hyfen.net/memex/&#34;&gt;blog posts&lt;/a&gt; seems to be a gold mine.&lt;/p&gt; &lt;p&gt;Also look at &lt;a href=&#34;https://github.com/hpi/hpi&#34;&gt;hpi&#39;s compilation&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#improve-the-way-of-launching-applications-with-i3wm&#34;&gt;Sketch how to improve the launching of applications with i3wm.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;In the past I tried installing &lt;a href=&#34;https://github.com/davatorium/rofi&#34;&gt;rofi&lt;/a&gt; without success, I should try again. If the default features are not enough, check &lt;a href=&#34;https://github.com/adi1090x/rofi&#34;&gt;adi1090x&#39;s custom resources&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#repository-orm&#34;&gt;Show the changes of repository-orm 0.3.1.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;+* Add &lt;code&gt;first&lt;/code&gt; and &lt;code&gt;last&lt;/code&gt; methods to the repositories. +* Make entity &lt;code&gt;id_&lt;/code&gt; definition optional. +* add &lt;code&gt;_model_name&lt;/code&gt; attribute to entities.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#quantified-self&#34;&gt;Add woop awesome quantified self resources to the research list.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#migrate-software-bug-tracker-to-a-vendor-free-one&#34;&gt;Add project to migrate software bug tracker to a vendor free one like &lt;code&gt;git-bug&lt;/code&gt;.&lt;/a&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#improve-the-notification-management-in-linux&#34;&gt;Improve the notification management in Linux.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Create new seed project to be able to group and silence the notifications under a custom logic. For example:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;If I want to focus on a task, only show the most important ones.&lt;/li&gt; &lt;li&gt;Only show alerts once every X minutes. Or define that I want to receive them the first 10 minutes of every hour.&lt;/li&gt; &lt;li&gt;If I&#39;m not working, silence all work alerts.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#improve-the-hard-drive-monitor-system&#34;&gt;Improve the hard drive monitor system.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Create new seed project to use something like &lt;a href=&#34;https://github.com/AnalogJ/scrutiny&#34;&gt;scrutiny&lt;/a&gt; (there&#39;s a &lt;a href=&#34;https://docs.linuxserver.io/images/docker-scrutiny&#34;&gt;linuxserver image&lt;/a&gt;) to collect and display the information. For alerts, use one of their &lt;a href=&#34;https://github.com/AnalogJ/scrutiny#notifications&#34;&gt;supported providers&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#aggregate-all-notifications&#34;&gt;Aggregate all notifications.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Instead of reading the email, github, gitlab, discourse, reddit notifications, aggregate all in one place and show them to the user in a nice command line interface.&lt;/p&gt; &lt;p&gt;For the aggregator server, my first choice would be &lt;a href=&#34;https://gotify.net/&#34;&gt;gotify&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#faker-optional&#34;&gt;Add faker-optional to the dormant plant projects.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#other&#34;&gt;Add seedling project to create factoryboy factories from pydantic models automatically.&lt;/a&gt;&lt;/li&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#inbox-management&#34;&gt;Explain the idea of how to improve the record of ideas, tasks,.&lt;/a&gt;&lt;/li&gt; &lt;li&gt;New: Add git-bug as an interesting distributed issue tracker.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#improve-the-reliability-of-the-open-science-collections&#34;&gt;Add the Improve the reliability of the Open Science collections project.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The current &lt;a href=&#34;https://lyz-code.github.io/blue-book/free_knowledge/&#34;&gt;free knowledge efforts&lt;/a&gt;: are based on the health of a collection of torrents. This project aims to create a command line tool or service that makes it easier to automate the seeding of ill torrents.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#monitor-and-notify-on-disk-prices&#34;&gt;Add the Monitor and notify on disk prices project.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://diskprices.com/&#34;&gt;Diskprices.com&lt;/a&gt; sorts the prices of the disks on the different amazon sites based on many filters. It will be interesting to have a service that monitors the data on this site and alerts the user once there is a deal that matches its criteria.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Reorganization: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#automating-computer-file-management&#34;&gt;Move the automation of computer file management project to the projects page.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Reorganization: Move the dying projects below the seeds as they are less important.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#self-hosted-map&#34;&gt;Introduce seedling self-hosted map project.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I love maps, as well as traveling and hiking. This project aims to create a web interface that let&#39;s me interact with the data gathered throughout my life. I&#39;d like to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Browse the waypoints and routes that I&#39;ve done.&lt;/li&gt; &lt;li&gt;Create routes and export the gpx.&lt;/li&gt; &lt;li&gt;Be able to search through the data&lt;/li&gt; &lt;li&gt;Plan trips&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#switch-to-a-better-browser&#34;&gt;Introduce the seed project to.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#life&#34;&gt;Add the Life seedling project.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Life is a real time sandbox role game where you play as yourself surviving in today&#39;s world.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#bruty&#34;&gt;Add bruty to the dormant plant projects.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/lyz-code/bruty&#34;&gt;bruty&lt;/a&gt; is a Python program to bruteforce dynamic web applications with Selenium.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Add rsarai hq to interesting sources for lifelogging.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#pynbox&#34;&gt;Introduce pynbox the inbox management tool.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://lyz-code.github.io/pynbox&#34;&gt;Pynbox&lt;/a&gt; is a tool to improve the management of ideas, tasks, references, suggestions when I&#39;m not in front of the computer. Right now I&#39;ve got Markor for Android to register these quicknotes, but the reality is that I don&#39;t act upon them, so it&#39;s just a log of tasks that never get done, and ideas, references and suggestions that aren&#39;t registered in my knowledge or media management systems.&lt;/p&gt; &lt;p&gt;On the computer there are also cases of tasks that are not worth registering in the task management system, or ideas that I get at a moment but don&#39;t have time to process at the moment.&lt;/p&gt; &lt;p&gt;The idea then is to automatically sync the Android quicknote with syncthing, and have a special format for the file that allows &lt;a href=&#34;https://lyz-code.github.io/pynbox&#34;&gt;&lt;code&gt;pynbox&lt;/code&gt;&lt;/a&gt; to extract the elements from that file to the &#34;inbox system&#34;. For example: + &lt;/p&gt; &lt;p&gt;Gets introduced in the &#34;inbox system&#34; as a task, a TV suggestion and an idea.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce nyxt as a solution for a better browser.&lt;/p&gt; &lt;p&gt;I&#39;ve just stumbled upon &lt;a href=&#34;https://nyxt.atlas.engineer/&#34;&gt;nyxt&lt;/a&gt; (&lt;a href=&#34;https://github.com/atlas-engineer/nyxt&#34;&gt;code&lt;/a&gt;), and it looks superb.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#shared-accounting&#34;&gt;Introduce the shared accounting seed project.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I use &lt;a href=&#34;https://lyz-code.github.io/blue-book/beancount/&#34;&gt;beancount&lt;/a&gt; for my personal accounting, I&#39;d like to have a system that integrates more less easily with beancount and let&#39;s do a shared accounting with other people, for example in trips. I&#39;ve used &lt;a href=&#34;https://settleup.io/&#34;&gt;settle up&lt;/a&gt; in the past but it requires access to their servers, and an account linked to google, facebook or one you register in their servers.&lt;/p&gt; &lt;p&gt;I&#39;ve looked at &lt;a href=&#34;https://github.com/nymanjens/facto&#34;&gt;facto&lt;/a&gt; but it uses a logic that doesn&#39;t apply to my case, it does a heavy use on a common account, instead +of minimizing the transactions between the people. I also tried &lt;a href=&#34;https://github.com/bertvandepoel/tabby#installation&#34;&gt;tabby&lt;/a&gt;, even though they still &lt;a href=&#34;https://github.com/bertvandepoel/tabby/issues/13&#34;&gt;don&#39;t support Docker&lt;/a&gt;, but it doesn&#39;t suit my case either :(.&lt;/p&gt; &lt;p&gt;Until a new solution shows up, I&#39;ll go with &lt;a href=&#34;https://github.com/koelleChristian/trickytripper&#34;&gt;Tricky Tripper&lt;/a&gt; available in F-Droid, and manage the expenses myself and periodically send the html reports to the rest of the group.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Add quickwit as an interesting database solution for personal knowledge search engine.&lt;/p&gt; &lt;/li&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#automate-email-management&#34;&gt;Promote the automation of email management project to seedling.&lt;/a&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#pomodoro-command-line&#34;&gt;Introduce the pomodoro command line seed project.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Command line to help with the &lt;a href=&#34;life_planning.md#pomodoro&#34;&gt;pomodoro workflow&lt;/a&gt;, besides the basic stuff it will interact with the task manager, &lt;a href=&#34;https://lyz-code.github.io/blue-book/activitywatch/&#34;&gt;activitywatch&lt;/a&gt; and the notifications system.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#create-an-ordered-list-of-digital-gardens&#34;&gt;Introduce the ordered list of digital gardens project.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use &lt;a href=&#34;https://github.com/best-of-lists/best-of&#34;&gt;best-of-lists&lt;/a&gt; to create an awesome list of digital gardens.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Clean up deprecated projects.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/#self-host-a-routing-web-application&#34;&gt;Add seed to self host a routing web application.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Host and play around with &lt;a href=&#34;https://github.com/abrensch/brouter&#34;&gt;brouter&lt;/a&gt; and &lt;a href=&#34;https://github.com/nrenner/brouter-web&#34;&gt;brouter-web&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;activism&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/anonymous_feedback/&#34;&gt;Activism&lt;/a&gt;&lt;/h2&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the anonymous feedback tool to improve diversity, equity and inclusion in an organization.&lt;/p&gt; &lt;p&gt;Anonymous Feedback is a communication tool where people share feedback to teammates or other organizational members while protecting their identities.&lt;/p&gt; &lt;p&gt;Until the safe space is built where direct feedback is viable, anonymous feedback gives these employees a mechanism to raise their concerns, practice their feedback-giving skills, test the waters, and understand how people perceive their constructive (and sometimes critical) opinions, thus building the needed trust.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Define Diversity, Equity and Inclusion.&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;&lt;em&gt;Diversity&lt;/em&gt; is the representation and acknowledgement of the multitudes of identities, experiences, and ways of moving through the world. This includes—but is not limited to—ability, age, citizenship status, criminal record and/or incarceration, educational attainment, ethnicity, gender, geographical location, language, nationality, political affiliation, religion, race, sexuality, socioeconomic status, and veteran status. Further, we recognize that each individual&#39;s experience is informed by intersections across multiple identities.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;em&gt;Equity&lt;/em&gt; seeks to ensure respect and equal opportunity for all, using all resources and tools to elevate the voices of under-represented and/or disadvantaged groups.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;em&gt;Inclusion&lt;/em&gt; is fostering an environment in which people of all identities are welcome, valued, and supported. An inclusive organization solicits, listens to, learns from, and acts on the contributions of all its stakeholders.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce Anti-transphobia.&lt;/p&gt; &lt;p&gt;Anti-transphobia being reductionist is the opposition to the collection of ideas and phenomena that encompass a range of negative attitudes, feelings or actions towards transgender people or transness in general. Transphobia can include fear, aversion, hatred, violence, anger, or discomfort felt or expressed towards people who do not conform to social gender expectations. It is often expressed alongside homophobic views and hence is often considered an aspect of homophobia.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/antitransphobia/#terf&#34;&gt;Introduce arguments against terf ideology.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/TERF&#34;&gt;TERF&lt;/a&gt; is an acronym for &lt;em&gt;trans-exclusionary radical feminist&lt;/em&gt;. The term originally applied to the minority of feminists that expressed transphobic sentiments such as the rejection of the assertion that trans women are women, the exclusion of trans women from women&#39;s spaces, and opposition to transgender rights legislation. The meaning has since expanded to refer more broadly to people with trans-exclusionary views who may have no involvement with radical feminism.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;antifascism&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/antifascism/&#34;&gt;Antifascism&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce antifascism.&lt;/p&gt; &lt;p&gt;Antifascism is a method of politics, a locus of individual and group self-indentification, it&#39;s a transnational movement that adapted preexisting socialist, anarchist, and communist currents to a sudden need to react to the fascist menace (&lt;a href=&#34;#references&#34;&gt;Mark p. 11&lt;/a&gt;). It&#39;s based on the idea that &lt;a href=&#34;#how-to-identify-fascism&#34;&gt;any oppression form&lt;/a&gt; can&#39;t be allowed, and should be actively fought with whatever means are necessary.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;antifascist-actions&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/antifascist_actions/&#34;&gt;Antifascist Actions&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/antifascist_actions/#a-fake-company-and-five-million-recycled-flyers&#34;&gt;A fake company and five million recycled flyers.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;A group of artists belonging to the &lt;a href=&#34;https://politicalbeauty.com/&#34;&gt;Center for political beauty&lt;/a&gt; created a fake company &lt;a href=&#34;https://www.flyerservice-hahn.de/&#34;&gt;Flyerservice Hahn&lt;/a&gt; and convinced more than 80 regional sections of the far right party AfD to hire them to deliver their electoral propaganda.&lt;/p&gt; &lt;p&gt;They gathered five million flyers, with a total weight of 72 tons. They justify that they wouldn&#39;t be able to lie to the people, so they did nothing in the broader sense of the word. They declared that they are the &lt;a href=&#34;https://www.youtube.com/watch?v=qcBVq-PtrpY&#34;&gt;&#34;world wide leader in the non-delivery of nazi propaganda&#34;&lt;/a&gt;. At the start of the electoral campaign, they went to the AfD stands, and they let their members to give them flyers the throw them to the closest bin. &#34;It&#39;s something that any citizen can freely do, we have only industrialized the process&#34;.&lt;/p&gt; &lt;p&gt;They&#39;ve done a &lt;a href=&#34;https://afd-muell.de/&#34;&gt;crowdfunding&lt;/a&gt; to fund the legal process that may result.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;feminism&#34;&gt;Feminism&lt;/h3&gt; &lt;h4 id=&#34;privileges&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/feminism/privileges/&#34;&gt;Privileges&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Feminist analysis of privileges and rights.&lt;/p&gt; &lt;p&gt;Privileges are a group of special structural benefits, social advantages, that a group holds over another. So they are elements that should be removed from our lives.&lt;/p&gt; &lt;p&gt;Some of the topics included are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;What&#39;s the difference between privilege and right&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/feminism/privileges/#what-can-we-do-to-fight-the-privileges&#34;&gt;What can we do to fight the privileges?&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;free-knowledge&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/free_knowledge/&#34;&gt;Free Knowledge&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce how to contribute to the free knowledge initiative.&lt;/p&gt; &lt;p&gt;One of the early principles of the internet has been to make knowledge free to everyone. &lt;a href=&#34;https://en.wikipedia.org/wiki/Alexandra_Elbakyan&#34;&gt;Alexandra Elbakyan&lt;/a&gt; of &lt;a href=&#34;https://sci-hub.do/&#34;&gt;Sci-Hub&lt;/a&gt;, bookwarrior of &lt;a href=&#34;https://libgen.fun/&#34;&gt;Library Genesis&lt;/a&gt;, &lt;a href=&#34;https://en.wikipedia.org/wiki/Aaron_Swartz&#34;&gt;Aaron Swartz&lt;/a&gt;, and countless unnamed others have fought to free science from the grips of for-profit publishers. Today, they do it working in hiding, alone, without acknowledgment, in fear of imprisonment, and even now wiretapped by the FBI. They sacrifice everything for one vision: Open Science.&lt;/p&gt; &lt;p&gt;If you want to know how to contribute, check the &lt;a href=&#34;https://lyz-code.github.io/blue-book/free_knowledge/&#34;&gt;article&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;life-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/life_management/&#34;&gt;Life Management&lt;/a&gt;&lt;/h2&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Reorganization: Split the life automation article into life management and process automation.&lt;/p&gt; &lt;p&gt;I understand life management as the act of analyzing yourself and your interactions with the world to define processes and automations that shape the way to efficiently achieve your goals.&lt;/p&gt; &lt;p&gt;I understand process automation as the act of analyzing yourself and your interactions with the world to find the way to reduce the time or willpower spent on your life processes.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;time-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/time_management/&#34;&gt;Time Management&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the time management concept.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Time_management&#34;&gt;Time management&lt;/a&gt; is the process of planning and exercising conscious control of time spent on specific activities, especially to increase effectiveness, efficiency, and productivity. It involves a juggling act of various demands upon a person relating to work, social life, family, hobbies, personal interests, and commitments with the finiteness of time. Using time effectively gives the person &#34;choice&#34; on spending or managing activities at their own time and expediency.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Start analyzing the ways to reduce the time spent doing unproductive tasks.&lt;/p&gt; &lt;p&gt;By &lt;a href=&#34;https://lyz-code.github.io/blue-book/time_management/#minimize-the-context-switches&#34;&gt;minimizing the context switches&lt;/a&gt; and &lt;a href=&#34;https://lyz-code.github.io/blue-book/time_management/#interruption-management&#34;&gt;managing the interruptions&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: &lt;a href=&#34;https://lyz-code.github.io/blue-book/time_management/#tool-management&#34;&gt;Explain how to improve your efficiency by better using your everyday tools.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Add two more ways to avoid loosing time in unproductive tasks.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/time_management/#avoid-lost-time-doing-nothing&#34;&gt;Avoid lost time doing nothing&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/time_management/#fix-your-environment&#34;&gt;Fix your environment&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/time_management/#meetings&#34;&gt;Explain how to manage meetings efficiently.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/time_management/#improve-your-state&#34;&gt;Explain how to improve efficiency by taking care of yourself.&lt;/a&gt;&lt;/li&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/time_management/#don&#39;t-wait,-switch-task&#34;&gt;Explain how to prevent blocks by efficiently switching mental processes.&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;task-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/action_management/&#34;&gt;Task Management&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the task management concept.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Task_management&#34;&gt;Task management&lt;/a&gt; is the process of managing a task through its life cycle. It involves planning, testing, tracking, and reporting. Task management can help either individual achieve goals, or groups of individuals collaborate and share knowledge for the accomplishment of collective goals.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Introduce the main task management tools.&lt;/p&gt; &lt;p&gt;The &lt;a href=&#34;https://lyz-code.github.io/blue-book/action_management/#inbox&#34;&gt;inbox&lt;/a&gt; does not refer only to your e-mail inbox. It is a broader concept that includes all the elements you have collected in different ways: tasks you have to do, ideas you have thought of, notes, bills, business cards, etc…&lt;/p&gt; &lt;p&gt;The &lt;a href=&#34;https://lyz-code.github.io/blue-book/action_management/#task-manager&#34;&gt;task manager&lt;/a&gt; tool to make your interaction with the tasks easier. You can start with the &lt;a href=&#34;https://lyz-code.github.io/blue-book/action_management/#the-simplest-task-manager&#34;&gt;simplest task manager&lt;/a&gt;, a markdown file in your computer with a list of tasks to do. Annotate only the actionable tasks that you need to do today, otherwise it can quickly grow to be unmanageable.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Add the benefits when you do task management well, and the side effects if you do it wrong.&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Improvement: Add a small guide on how to introduce yourself into task management.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;task-management-workflows&#34;&gt;&lt;a href=&#34;life_planning.md&#34;&gt;Task Management Workflows&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the main task management workflows.&lt;/p&gt; &lt;p&gt;Task management can be done at different levels. All of them help you in different ways to reduce the mental load, each also gives you extra benefits that can&#39;t be gained by the others. Going from lowest to highest abstraction level we have:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Pomodoro.&lt;/li&gt; &lt;li&gt;Task plan.&lt;/li&gt; &lt;li&gt;Day plan.&lt;/li&gt; &lt;li&gt;Week plan.&lt;/li&gt; &lt;li&gt;Month plan.&lt;/li&gt; &lt;li&gt;Semester plan.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;In the commit I&#39;ve detailed the &lt;a href=&#34;life_planning.md#pomodoro&#34;&gt;Pomodoro technique&lt;/a&gt; and the &lt;a href=&#34;life_planning.md#task-plan&#34;&gt;task&lt;/a&gt;, &lt;a href=&#34;life_planning.md#day-plan&#34;&gt;day&lt;/a&gt; and &lt;a href=&#34;life_planning.md#week-plan&#34;&gt;week&lt;/a&gt; plans.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;life_planning.md#hype-flow-versus-a-defined-plan&#34;&gt;Explain the difference of surfing the hype flow versus following a defined plan.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;interruption-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/interruption_management/&#34;&gt;Interruption Management&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the interruption management concept.&lt;/p&gt; &lt;p&gt;Interruption management is the &lt;a href=&#34;https://lyz-code.github.io/blue-book/life_management/&#34;&gt;life management&lt;/a&gt; area that gathers the processes to minimize the time and willpower toll consumed by interruptions.&lt;/p&gt; &lt;p&gt;The article proposes a way to analyze your existent interruptions and define how can you improve your interaction with them. I&#39;ve applied it both to my &lt;a href=&#34;https://lyz-code.github.io/blue-book/work_interruption_analysis/&#34;&gt;work&lt;/a&gt; and &lt;a href=&#34;https://lyz-code.github.io/blue-book/personal_interruption_analysis/&#34;&gt;personal&lt;/a&gt; interruptions.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: &lt;a href=&#34;https://lyz-code.github.io/blue-book/interruption_management/#workflow&#34;&gt;Explain what to do once you have the interruption analysis.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;work-interruption-analysis&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/work_interruption_analysis/&#34;&gt;Work Interruption Analysis&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;Improvement: Add analysis of instant message interruptions.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;personal-interruption-analysis&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/personal_interruption_analysis/&#34;&gt;Personal Interruption Analysis&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;Improvement: Add analysis of instant message interruptions.&lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;money-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/money_management/&#34;&gt;Money Management&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;Reorganization: Move the accounting automation to money management.&lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;email-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/email_management/&#34;&gt;Email Management&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;New: Explain how I configure and interact with email efficiently.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;email-automation&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/email_automation/&#34;&gt;Email Automation&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Explain how setup an infrastructure to automate.&lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;music-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/music_management/&#34;&gt;Music Management&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;New: Introduce how I manage my music library.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;musicbrainz&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/musicbrainz/&#34;&gt;MusicBrainz&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: How to contribute to MusicBrainz.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://musicbrainz.org&#34;&gt;MusicBrainz&lt;/a&gt; is an open music encyclopedia that collects music metadata and makes it available to the public.&lt;/p&gt; &lt;p&gt;MusicBrainz aims to be:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The ultimate source of music information by allowing anyone to contribute and releasing the data under open licenses.&lt;/li&gt; &lt;li&gt;The universal lingua franca for music by providing a reliable and unambiguous form of music identification, enabling both people and machines to have meaningful conversations about music.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Like Wikipedia, MusicBrainz is maintained by a global community of users and we want everyone — including you — to &lt;a href=&#34;https://musicbrainz.org/doc/How_to_Contribute&#34;&gt;participate and contribute&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;book-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/book_management/&#34;&gt;Book Management&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the book management concept.&lt;/p&gt; &lt;p&gt;Book management is the set of systems and processes to get and categorize books so it&#39;s easy to browse and discover new content. It involves the next actions:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Automatically index and download metadata of new books.&lt;/li&gt; &lt;li&gt;Notify the user when a new book is added.&lt;/li&gt; &lt;li&gt;Monitor the books of an author, and get them once they are released.&lt;/li&gt; &lt;li&gt;Send books to the e-reader.&lt;/li&gt; &lt;li&gt;A nice interface to browse the existent library, with the possibility of filtering by author, genre, years, tags or series.&lt;/li&gt; &lt;li&gt;An interface to preview or read the items.&lt;/li&gt; &lt;li&gt;An interface to rate and review library items.&lt;/li&gt; &lt;li&gt;An interface to discover new content based on the ratings and item metadata.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;I haven&#39;t yet found a single piece of software that fulfills all these needs, in the article I tell you about &lt;a href=&#34;https://readarr.com/&#34;&gt;Readarr&lt;/a&gt;, &lt;a href=&#34;https://github.com/janeczku/calibre-web&#34;&gt;Calibre-web&lt;/a&gt;, [calibre]((&lt;a href=&#34;https://manual.calibre-ebook.com/&#34;&gt;https://manual.calibre-ebook.com/&lt;/a&gt;), &lt;a href=&#34;https://getpolarized.io/&#34;&gt;Polar bookself&lt;/a&gt;, &lt;a href=&#34;http://www.gcstar.org/&#34;&gt;GCStar&lt;/a&gt;, and how they interact with each other.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Add link to the calibre-web kobo integration project.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;map-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/map_management/&#34;&gt;Map Management&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: How I manage maps in my life.&lt;/p&gt; &lt;p&gt;For navigating on the go, I strongly recommend &lt;a href=&#34;https://lyz-code.github.io/blue-book/osmand/&#34;&gt;OSMand+&lt;/a&gt;, for browsing maps in the browser, use &lt;a href=&#34;https://osm.org&#34;&gt;OpenStreetMaps&lt;/a&gt; or &lt;a href=&#34;https://www.cyclosm.org&#34;&gt;CyclOSM&lt;/a&gt; if you want to move by bike.&lt;/p&gt; &lt;p&gt;To plan routes, you can use &lt;a href=&#34;https://brouter.de/brouter-web&#34;&gt;brouter.de&lt;/a&gt;, it works perfectly for bikes. For hiking is awesome too, it shows you a lot of data needed to plan your tracks (check the settings on the right). If you want to invest a little more time, you can even set your &lt;a href=&#34;https://github.com/poutnikl/Brouter-profiles/wiki/Hiking-profiles&#34;&gt;personalize profiles&lt;/a&gt;, so that the routing algorithm prioritizes the routes to your desires. It&#39;s based on &lt;a href=&#34;https://github.com/abrensch/brouter&#34;&gt;brouter&lt;/a&gt; and both can be &lt;a href=&#34;https://github.com/nrenner/brouter-web&#34;&gt;self-hosted&lt;/a&gt;, although &lt;a href=&#34;https://github.com/abrensch/brouter/issues/359&#34;&gt;brouter does not yet use Docker&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;instant-messages-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/instant_messages_management/&#34;&gt;Instant Messages Management&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;New: Explain how I configure and interact with chat applications efficiently.&lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;process-automation&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/process_automation/&#34;&gt;Process Automation&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;Improvement: Add xkcd comics that gather the essence and pitfalls of process automation.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;virtual-assistant&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/virtual_assistant/&#34;&gt;Virtual Assistant&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Introduce project with kalliope.&lt;/li&gt; &lt;li&gt;New: Explain the Speech-To-Text open source solutions.&lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;health&#34;&gt;Health&lt;/h2&gt; &lt;h3 id=&#34;sleep&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/sleep/&#34;&gt;Sleep&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/sleep/#the-sleep-cycle&#34;&gt;Explain the sleep cycle.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Humans cycle through two types of sleep in a regular pattern throughout the night with a period of 90 minutes. They were called non-rapid eye movement (NREM) and rapid eye movement (REM).&lt;/p&gt; &lt;p&gt;I answer the questions:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;What is the period of the REM/NREM cycle?&lt;/li&gt; &lt;li&gt;What happens to your body in REM and NREM phases?&lt;/li&gt; &lt;li&gt;How does the ratio of REM/NREM changes throughout the night? with a possible explanation.&lt;/li&gt; &lt;li&gt;Why sleeping 6 hours can make you loose up to 90% of your REM or NREM phases?&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/sleep/#sleeping-time-and-sense-distortions&#34;&gt;Explain sleeping time and sense distortions.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Answer the questions:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Why time feels longer in our dreams?&lt;/li&gt; &lt;li&gt;How do we loose awareness of the outside world when sleeping?&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;teeth&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/teeth/&#34;&gt;Teeth&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Explain how to take care of your teeth.&lt;/p&gt; &lt;p&gt;A full guide on why should you take care of your teeth, the description on how the basic oral diseases work, why and how to brush your teeth, floss and usage of mouthwash&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Recommend a regular clean instead of a deep clean.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;deep-cleaning&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/teeth_deep_cleaning/&#34;&gt;Deep cleaning&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Explain what a deep cleaning is and when should you do it.&lt;/p&gt; &lt;p&gt;Analyze the reasons why would you need to do this procedure, how it works, when you need to do it, side effects and scientific evidences of it&#39;s effectiveness.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;fitness-tracker&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/fitness_band/&#34;&gt;Fitness Tracker&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the fitness band in your life automation.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Activity_tracker&#34;&gt;Fitness tracker&lt;/a&gt; or activity trackers are devices or applications for monitoring and tracking fitness-related metrics such as distance walked or run, calorie consumption, and in some cases heartbeat. It is a type of wearable computer.&lt;/p&gt; &lt;p&gt;Explain also why it&#39;s interesting&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Discovery of wasp-os and Colmi P8.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/daniel-thompson/wasp-os&#34;&gt;wasp-os&lt;/a&gt; is an open source firmware for smart watches that are based on the nRF52 family of microcontrollers. Fully supported by &lt;a href=&#34;https://lyz-code.github.io/blue-book/gadgetbridge/&#34;&gt;gadgetbridge&lt;/a&gt;, Wasp-os features full heart rate monitoring and step counting support together with multiple clock faces, a stopwatch, an alarm clock, a countdown timer, a calculator and lots of other games and utilities. All of this, and still with access to the MicroPython REPL for interactive tweaking, development and testing.&lt;/p&gt; &lt;p&gt;One of the supported devices, the &lt;a href=&#34;https://wasp-os.readthedocs.io/en/latest/install.html#colmi-p8&#34;&gt;Colmi P8&lt;/a&gt;, looks really good.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;amazfit-band-5&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/amazfit_band_5/&#34;&gt;Amazfit Band 5&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add insights on sleep detection.&lt;/p&gt; &lt;p&gt;The sleep tracking using Gadgetbridge is not &lt;a href=&#34;https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Huami-Deep-Sleep-Detection&#34;&gt;good at all&lt;/a&gt;. After two nights, the band has not been able to detect when I woke in the middle of the night, or when I really woke up, as I usually stay in the bed for a time before standing up. I&#39;ll try with the proprietary application soon and compare results.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Explain how to upgrade the firmware.&lt;/p&gt; &lt;p&gt;Gadgetbridge people have a &lt;a href=&#34;https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Band-5-Firmware-Update&#34;&gt;guide on how to upgrade the firmware&lt;/a&gt;, you need to get the firmware from the &lt;a href=&#34;https://geekdoing.com/threads/amazfit-band-5-original-firmwares-resources-fonts.2331/&#34;&gt;geek doing forum&lt;/a&gt; though, so it is interesting to create an account and watch the post.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Add insights on sleep tracking.&lt;/p&gt; &lt;p&gt;You can&#39;t use the Withings sleep analyzer without their app (as expected), maybe the &lt;a href=&#34;https://github.com/karlicoss/HPI/blob/master/my/emfit/__init__.py&#34;&gt;Emfit QS&lt;/a&gt; is the way to go.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;coding&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vuejs/&#34;&gt;Coding&lt;/a&gt;&lt;/h2&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Vue.js.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://vuejs.org&#34;&gt;Vue.js&lt;/a&gt; is a progressive framework for building user interfaces.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;generic-coding-practices&#34;&gt;Generic Coding Practices&lt;/h3&gt; &lt;h4 id=&#34;program-versioning&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/versioning/&#34;&gt;Program Versioning&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Define how to use versioning in software.&lt;/p&gt; &lt;p&gt;A &lt;strong&gt;long&lt;/strong&gt; article on how to use versioning both as a developer and as a consumer. It includes:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/versioning/#deciding-what-version-system-to-use-for-your-programs&#34;&gt;Deciding what version system to use for your programs&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/versioning/#how-to-evolve-your-code-version&#34;&gt;How to evolve your code version&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/versioning/#deciding-how-to-manage-the-versions-of-your-dependencies&#34;&gt;Deciding how to manage the versions of your dependencies&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;A huge rant on &lt;a href=&#34;https://lyz-code.github.io/blue-book/versioning/#upper-version-pinning&#34;&gt;Upper version pinning&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/versioning/#lower-version-pinning&#34;&gt;When to use lower version pinning&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/versioning/#automatically-upgrade-and-test-your-dependencies&#34;&gt;How to automatically upgrade and test your dependencies&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/versioning/#monitor-your-dependencies-evolution&#34;&gt;Monitor your dependencies evolution&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;keep-a-changelog&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/semantic_versioning/&#34;&gt;Keep a Changelog&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the Changelog practice.&lt;/p&gt; &lt;p&gt;A changelog is a file which contains a curated, chronologically ordered list of notable changes for each version of a project.&lt;/p&gt; &lt;p&gt;It&#39;s purpose is to make it easier for users and contributors to see precisely what notable changes have been made between each release (or version) of the project.&lt;/p&gt; &lt;p&gt;In the article we added:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/changelog/#changelog-guidelines&#34;&gt;Guidelines&lt;/a&gt; on how to build good changelogs&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/changelog/#how-to-reduce-the-effort-required-to-maintain-a-changelog&#34;&gt;How to reduce the effort required to maintain a changelog&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce Semantic Versioning.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://semver.org/&#34;&gt;Semantic Versioning&lt;/a&gt; is a way to define your program&#39;s version based on the type of changes you&#39;ve introduced. It&#39;s defined as a three-number string (separated with a period) in the format of &lt;code&gt;MAJOR.MINOR.PATCH&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Also included in the article is:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/semantic_versioning/#when-to-do-a-major-release&#34;&gt;When to do a major release&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/semantic_versioning/#semantic-versioning-system-problems&#34;&gt;Semantic versioning system problems&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;calendar-versioning&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/documentation/&#34;&gt;Calendar Versioning&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Start explaining how to write good documentation for a software project.&lt;/p&gt; &lt;p&gt;It doesn&#39;t matter how good your program is, because if its documentation is not good enough, people will not use it.&lt;/p&gt; &lt;p&gt;People working with software need different kinds of documentation at different times, in different circumstances, so good software documentation needs them all. In this first iteration, I define the five kinds of documentation, and give the ideas to write good introduction and get started sections.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce Calendar Versioning.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://calver.org/&#34;&gt;Calendar Versioning&lt;/a&gt; is a versioning convention based on your project&#39;s release calendar, instead of arbitrary numbers.&lt;/p&gt; &lt;p&gt;CalVer suggests version number to be in format of: &lt;code&gt;YEAR.MONTH.sequence&lt;/code&gt;. For example, &lt;code&gt;20.1&lt;/code&gt; indicates a release in 2020 January, while &lt;code&gt;20.5.2&lt;/code&gt; indicates a release that occurred in 2020 May, while the &lt;code&gt;2&lt;/code&gt; indicates this is the third release of the month.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;python&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/python/&#34;&gt;Python&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;New: Explain how to check if a loop ends completely.&lt;/li&gt; &lt;li&gt;New: Explain how to merge lists and dictionaries.&lt;/li&gt; &lt;li&gt;New: Explain how to create your own exceptions.&lt;/li&gt; &lt;li&gt;New: Add python landing page.&lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Add aiomultiprocess to the list of libraries to test.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/omnilib/aiomultiprocess&#34;&gt;aiomultiprocess&lt;/a&gt;: Presents a simple interface, while running a full AsyncIO event loop on each child process, enabling levels of concurrency never before seen in a Python application. Each child process can execute multiple coroutines at once, limited only by the workload and number of cores available.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/python/#how-to-write-good-documentation&#34;&gt;Add interesting links on how to write good documentation.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I would like to refactor &lt;a href=&#34;https://documentation.divio.com/introduction/&#34;&gt;divio&#39;s&lt;/a&gt; and &lt;a href=&#34;https://v3.vuejs.org/guide/contributing/writing-guide.html#principles&#34;&gt;Vue&#39;s&lt;/a&gt; guidelines and apply it to my projects.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Add FastAPI docs as a model to study and follow.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add apprise to the interesting libraries to explore.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/caronc/apprise&#34;&gt;apprise&lt;/a&gt;: Allows you to send a notification to almost all of the most popular notification services available to us today such as: Linux, Telegram, Discord, Slack, Amazon SNS, Gotify, etc. Look at &lt;a href=&#34;https://github.com/caronc/apprise#supported-notifications&#34;&gt;all the supported notifications&lt;/a&gt; &lt;code&gt;(¬º-°)¬&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add kivi and kivimd to the interesting libraries to explore.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://kivy.org/&#34;&gt;kivi&lt;/a&gt; is used to create android/Linux/iOS/Windows applications with python. Use it with &lt;a href=&#34;https://github.com/kivymd/KivyMD&#34;&gt;kivimd&lt;/a&gt; to make it beautiful, check &lt;a href=&#34;https://github.com/HeaTTheatR/Articles&#34;&gt;the examples&lt;/a&gt; and the &lt;a href=&#34;https://kivymd.readthedocs.io/en/latest/&#34;&gt;docs&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add parso library to interesting libraries to explore.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/davidhalter/parso&#34;&gt;parso&lt;/a&gt; is a library to parse Python code.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Add textual as interesting library to explore.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/willmcgugan/textual&#34;&gt;textual&lt;/a&gt;: Textual is a TUI (Text User Interface) framework for Python using Rich as a renderer.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add schedule to interesting libraries to explore.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/dbader/schedule&#34;&gt;schedule&lt;/a&gt; is a Python job scheduling for humans. Run Python functions (or any other callable) periodically using a friendly syntax.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add tryceratops to interesting linters to try.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/guilatrova/tryceratops&#34;&gt;tryceratops&lt;/a&gt; is a linter of exceptions.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pydantic-field-types&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/asyncio/&#34;&gt;Pydantic Field Types&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the asyncio library.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://docs.python.org/3/library/asyncio.html&#34;&gt;asyncio&lt;/a&gt; is a library to write concurrent code using the async/await syntax.&lt;/p&gt; &lt;p&gt;asyncio is used as a foundation for multiple Python asynchronous frameworks that provide high-performance network and web-servers, database connection libraries, distributed task queues, etc.&lt;/p&gt; &lt;p&gt;asyncio is often a perfect fit for IO-bound and high-level structured network code.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/asyncio/#limit-concurrency&#34;&gt;Limit concurrency.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use &lt;a href=&#34;https://docs.python.org/3/library/asyncio-sync.html#semaphores&#34;&gt;&lt;code&gt;asyncio.Semaphore&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;sem&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Semaphore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;# work with shared resource&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pydantic_types/#using-constrained-strings-in-list-attributes&#34;&gt;Using constrained strings in list attributes.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;re&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pydantic&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pydantic&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Field&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;typing&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Regex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pydantic&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ConstrainedStr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;regex&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;re&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;compile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;^[0-9a-z_]*$&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pydantic&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BaseModel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;regex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Regex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;regex&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;abc&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;123&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;asdf&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]})&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pipenv&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/requests_mock/&#34;&gt;Pipenv&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Explain how to set cookies and headers in responses.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce the AWS SDK library and explain how to test it.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://boto3.amazonaws.com/v1/documentation/api/latest/index.html&#34;&gt;Boto3&lt;/a&gt; is the AWS SDK for Python to create, configure, and manage AWS services, such as Amazon Elastic Compute Cloud (Amazon EC2) and Amazon Simple Storage Service (Amazon S3). The SDK provides an object-oriented API as well as low-level access to AWS services.&lt;/p&gt; &lt;p&gt;For &lt;a href=&#34;https://lyz-code.github.io/blue-book/boto3/#testing&#34;&gt;testing&lt;/a&gt;, try to use &lt;a href=&#34;https://lyz-code.github.io/blue-book/boto3/#moto&#34;&gt;moto&lt;/a&gt;, using the &lt;a href=&#34;https://botocore.amazonaws.com/v1/documentation/api/latest/reference/stubber.html&#34;&gt;Botocore&#39;s stubber&lt;/a&gt; as fallback option.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Explain how to test ec2, route53, s3, and rds resources.&lt;/p&gt; &lt;/li&gt; &lt;li&gt;New: Explain how to test vpc and auto scaling group resources.&lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Explain how to extract the instance when testing autoscaling groups.&lt;/p&gt; &lt;p&gt;Also track the &lt;a href=&#34;https://lyz-code.github.io/blue-book/boto3/#issues&#34;&gt;issue to add support to launch templates&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/boto3/#test-security-groups&#34;&gt;Explain how to test security groups.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/boto3/#test-route53&#34;&gt;Add note that pagination is not yet supported when testing route53.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I&#39;ve &lt;a href=&#34;https://github.com/spulec/moto/issues/3879&#34;&gt;opened an issue&lt;/a&gt; to solve it.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/boto3/#test-iam-users&#34;&gt;Explain how to test IAM users and groups.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Improvement: Monitor motor issue with the &lt;code&gt;cn-north-1&lt;/code&gt; rds and autoscaling endpoints.&lt;/li&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/prompt_toolkit_fullscreen_applications/#testing&#34;&gt;Testing full screen applications.&lt;/a&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/prompt_toolkit_fullscreen_applications/#pass-more-than-one-key&#34;&gt;Pass more than one key.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To map an action to two key presses use &lt;code&gt;kb.add(&#39;g&#39;, &#39;g&#39;)&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/prompt_toolkit_fullscreen_applications/#styles&#34;&gt;Add note on how to debug the styles of the components.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Set the style to &lt;code&gt;bg:#dc322f&lt;/code&gt; and it will be highlighted in red.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/prompt_toolkit_fullscreen_applications/#conditional-containers&#34;&gt;How to use Conditional Containers.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;prompt_toolkit.layout&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ConditionalContainer&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;prompt_toolkit.filters.utils&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;to_filter&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;show_header&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;ConditionalContainer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;Label&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;This is an optional text&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;filter&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;to_filter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;show_header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce the pipenv package manager.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/pypa/pipenv&#34;&gt;Pipenv&lt;/a&gt; is a tool that aims to bring the best of all packaging worlds (bundler, composer, npm, cargo, yarn, etc.) to the Python world.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;poetry&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/type_hints/&#34;&gt;Poetry&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Improvement: Explain how to ignore a linter error and a type error.&lt;/p&gt; &lt;p&gt;With &lt;code&gt;# type: ignore # noqa: W0212&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/type_hints/#allow-any-subclass&#34;&gt;Explain how to define the type hints of functions and methods that use subclasses.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It&#39;s a complex topic that has taken me many months to get it right :).&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/type_hints/#type-hints-of-generators&#34;&gt;Explain how to write type hints for generator functions.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Explain how to log in using pass.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pass&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;show&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dockerhub&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;login&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--username&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;foo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--password-stdin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Explain how not to store the credentials in plaintext.&lt;/p&gt; &lt;p&gt;It doesn&#39;t work, don&#39;t go this painful road and assume that docker is broken.&lt;/p&gt; &lt;p&gt;The official steps are horrible, and once you&#39;ve spent two hours debugging them, you &lt;a href=&#34;https://github.com/docker/docker-credential-helpers/issues/154&#34;&gt;won&#39;t be able to push or pull images with your user&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Explain how to change the command line help description.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#how-to-keep-containers-updated&#34;&gt;Explain how to use watchtower to keep docker containers updated.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;With &lt;a href=&#34;https://containrrr.dev/watchtower/&#34;&gt;watchtower&lt;/a&gt; you can update the running version of your containerized app simply by pushing a new image to the Docker Hub or your own image registry. Watchtower will pull down your new image, gracefully shut down your existing container and restart it with the same options that were used when it was deployed initially.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Explain how to run the watchtower checks immediately.&lt;/p&gt; &lt;p&gt;With the &lt;code&gt;--run-once&lt;/code&gt; flag&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/click/#invoke-other-commands-from-a-command&#34;&gt;Invoke other commands from a command.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This is a pattern that is generally discouraged with Click, but possible nonetheless. For this, you can use the &lt;code&gt;Context.invoke()&lt;/code&gt; or &lt;code&gt;Context.forward()&lt;/code&gt; methods.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/type_hints/#define-a-typevar-with-restrictions&#34;&gt;Define a TypeVar with restrictions.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;typing&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;TypeVar&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;AnyStr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;TypeVar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;AnyStr&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bytes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/type_hints/#use-a-constrained-typevar-in-the-definition-of-a-class-attributes&#34;&gt;Use a constrained TypeVar in the definition of a class attributes.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you try to use a &lt;code&gt;TypeVar&lt;/code&gt; in the definition of a class attribute:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;File&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Model a computer file.&#34;&#34;&#34;&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Optional&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AnyStr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# mypy error!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/mypy/&#34;&gt;mypy&lt;/a&gt; will complain with &lt;code&gt;Type variable AnyStr is unbound [valid-type]&lt;/code&gt;, to solve it, you need to make the class inherit from the &lt;code&gt;Generic[AnyStr]&lt;/code&gt;.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;File&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Generic&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AnyStr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Model a computer file.&#34;&#34;&#34;&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Optional&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AnyStr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Deeply introduce Poetry, a python package manager.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/python-poetry/poetry&#34;&gt;Poetry&lt;/a&gt; is a command line program that helps you declare, manage and install dependencies of Python projects, ensuring you have the right stack everywhere.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/python_poetry/#debugging-why-a-package-is-not-updated-to-the-latest-version&#34;&gt;Debugging why a package is not updated to the latest version.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/python_poetry/#checking-what-package-is-using-a-dependency&#34;&gt;Checking what package is using a dependency.&lt;/a&gt;&lt;/li&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/python_poetry/#configuration&#34;&gt;Try to use &lt;code&gt;pass&lt;/code&gt; as a keyring backend to store the PYPI token.&lt;/a&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Warn against upper version pinning.&lt;/p&gt; &lt;p&gt;The main problem is that &lt;code&gt;poetry add&lt;/code&gt; does &lt;a href=&#34;https://lyz-code.github.io/blue-book/versioning/#upper-version-pinning&#34;&gt;upper pinning of dependencies&lt;/a&gt; by default, which is a &lt;strong&gt;really bad idea&lt;/strong&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;dash&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/python_logging/&#34;&gt;Dash&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Explain how to log python program exceptions better than to a file.&lt;/p&gt; &lt;p&gt;Using &lt;code&gt;logging&lt;/code&gt; to write write exceptions and breadcrumbs to a file might not be the best solution because unless you look at it directly most errors will pass unnoticed.&lt;/p&gt; &lt;p&gt;To actively monitor and react to code exceptions use an application monitoring platform like &lt;a href=&#34;https://sentry.io/welcome/&#34;&gt;sentry&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;In the article I explain what are the advantages of using this solution and do a comparison between Sentry and &lt;a href=&#34;https://glitchtip.com&#34;&gt;GlitchTip&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/dash/#testing&#34;&gt;Testing Dash applications.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;dash.testing&lt;/code&gt; provides some off-the-rack pytest fixtures and a minimal set of testing APIs with our internal crafted best practices at the integration level. The commit includes a simple example and some guides on how to test Dash application.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/python_sh/#testing&#34;&gt;Test programs that use &lt;code&gt;sh&lt;/code&gt;.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;sh&lt;/code&gt; can be patched in your tests the typical way, with &lt;code&gt;unittest.mock.patch()&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;unittest.mock&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;patch&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;sh&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;get_something&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sh&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pwd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

&lt;span class=&#34;nd&#34;&gt;@patch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;sh.pwd&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;create&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;test_something&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pwd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;pwd&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;return_value&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;/&#34;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;get_something&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;/&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;code-styling&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_code_styling/&#34;&gt;Code Styling&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Improvement: Don&#39;t use try-except to initialize dictionaries.&lt;/p&gt; &lt;p&gt;Instead of:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;dictionary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;key&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;KeyError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;dictionary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;key&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;dictionary&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setdefault&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;key&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce the awesome, life saving library &lt;code&gt;pydantic_factories&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/Goldziher/pydantic-factories&#34;&gt;Pydantic factories&lt;/a&gt; is a library offers powerful mock data generation capabilities for pydantic based models and dataclasses. It automatically creates &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/factoryboy/&#34;&gt;FactoryBoy&lt;/a&gt; factories from a &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pydantic/&#34;&gt;pydantic&lt;/a&gt; model.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;datetime&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;date&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;typing&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Union&lt;/span&gt;

&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pydantic&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;BaseModel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UUID4&lt;/span&gt;

&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pydantic_factories&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ModelFactory&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Person&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BaseModel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UUID4&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;hobbies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Union&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;birthday&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Union&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;date&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;PersonFactory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ModelFactory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;__model__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Person&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;PersonFactory&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;build&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Reorganization: Moved the semantic versioning commit guidelines to the semver article.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;deepdiff&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/deepdiff/&#34;&gt;DeepDiff&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Remove murmur from the installation steps.&lt;/p&gt; &lt;p&gt;It seems it&#39;s the default for the new versions&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Add warning that regular expressions are not yet supported.&lt;/p&gt; &lt;p&gt;Until &lt;a href=&#34;https://github.com/seperman/deepdiff/pull/239&#34;&gt;#239&lt;/a&gt; is merged, the official library doesn&#39;t support searching for regular expressions. You can use &lt;a href=&#34;https://github.com/lyz-code/deepdiff&#34;&gt;my fork&lt;/a&gt; instead.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Remove advice to use my fork instead.&lt;/p&gt; &lt;p&gt;The original one has already merged my &lt;a href=&#34;https://github.com/seperman/deepdiff/pull/239&#34;&gt;PR&lt;/a&gt; &lt;code&gt;＼\ ٩( ᐛ )و /／&lt;/code&gt;. Beware though as the &lt;code&gt;regexp&lt;/code&gt; are not enabled by default (against my will). You need to use the &lt;code&gt;use_regexp=True&lt;/code&gt; as an argument to &lt;code&gt;grep&lt;/code&gt; or &lt;code&gt;DeepSearch&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;properties&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/factoryboy/&#34;&gt;Properties&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Explain how to generate your own attributes.&lt;/p&gt; &lt;p&gt;We earlier used lazy_attribute but if you want to use Faker inside the attribute definition, you&#39;re going to have a bad time. The new solution uses the creation of custom Fake providers.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/factoryboy/#word-from-enum-choices&#34;&gt;Explain how to use &lt;code&gt;Enum&lt;/code&gt; with factoryboy.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/factoryboy/#automatically-generate-a-factory-from-a-pydantic-model&#34;&gt;Automatically generate a factory from a pydantic model.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Sadly &lt;a href=&#34;https://github.com/FactoryBoy/factory_boy/issues/869&#34;&gt;it&#39;s not yet supported&lt;/a&gt;, &lt;a href=&#34;https://github.com/FactoryBoy/factory_boy/issues/836&#34;&gt;it will at some point though&lt;/a&gt;. If you&#39;re interested in following this path, you can start with &lt;a href=&#34;https://gist.github.com/mgaitan/dcbe08bf44a5af696f2af752624ac11b&#34;&gt;mgaitan snippet&lt;/a&gt; for dataclasses.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Give an overview on Python&#39;s @property decorator.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;package-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/faker/&#34;&gt;Package Management&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Explain how to create your own provider.&lt;/p&gt; &lt;p&gt;Useful to generate custom objects for testing purposes.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/faker/#create-optional-data&#34;&gt;Explain how to create &lt;code&gt;Optional&lt;/code&gt; data.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://lyz-code.github.io/faker-optional/&#34;&gt;&lt;code&gt;faker-optional&lt;/code&gt;&lt;/a&gt; is a custom faker provider that acts as a wrapper over other Faker providers to return their value or &lt;code&gt;None&lt;/code&gt;. Useful to create data of type &lt;code&gt;Optional[Any]&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/faker/#create-a-random-string-with-a-defined-format&#34;&gt;Create a random string with a defined format.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;faker&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pystr_format&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;id-#######{{random_letter}}&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;&#39;id-6443059M&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/faker/#create-an-ip-address&#34;&gt;Create an IP address.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;faker&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ipv4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you want a CIDR, use &lt;code&gt;network=True&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Compare Poetry, Pipenv and PDM package management tools.&lt;/p&gt; &lt;p&gt;Pipenv has broad support. It is an official project of the Python Packaging Authority, alongside pip. It&#39;s also supported by the Heroku Python buildpack, which is useful for anyone with Heroku or Dokku-based deployment strategies.&lt;/p&gt; &lt;p&gt;Poetry is a one-stop shop for dependency management and package management. It simplifies creating a package, managing its dependencies, and publishing it. Compared to Pipenv, Poetry&#39;s separate add and install commands are more explicit, and it&#39;s faster for everything except for a full dependency install.&lt;/p&gt; &lt;p&gt;I liked Poetry most, and in the end I didn&#39;t analyze &lt;code&gt;pdm&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/python_package_management/#solver&#34;&gt;Describe what a dependency solver does.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;A Solver tries to find a working set of dependencies that all agree with each other. By looking back in time, it’s happy to solve very old versions of packages if newer ones are supposed to be incompatible. This can be helpful, but is slow, and also means you can easily get a very ancient set of packages when you thought you were getting the latest versions.&lt;/p&gt; &lt;p&gt;In the section we compare Pip&#39;s and Poetry&#39;s solver.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/python_package_management/#poetry&#34;&gt;Add downsides of Poetry.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It does upper version capping by default, which is becoming &lt;a href=&#34;https://lyz-code.github.io/blue-book/versioning/#upper-version-pinning&#34;&gt;a big problem&lt;/a&gt; in the Python environment.&lt;/p&gt; &lt;p&gt;This is specially useless when you add dependencies that follow &lt;a href=&#34;https://lyz-code.github.io/blue-book/calendar_versioning/&#34;&gt;CalVer&lt;/a&gt;. &lt;code&gt;poetry add&lt;/code&gt; packaging will still do &lt;code&gt;^21&lt;/code&gt; for the version it adds. You shouldn’t be capping versions, but you really shouldn’t be capping CalVer.&lt;/p&gt; &lt;p&gt;It&#39;s equally troublesome that it upper pins &lt;a href=&#34;https://lyz-code.github.io/blue-book/versioning/#pinning-the-python-version-is-special&#34;&gt;the python version&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;fastapi&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/&#34;&gt;FastAPI&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce FastAPI the pydantic friendly python framework to build APIs.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://fastapi.tiangolo.com/&#34;&gt;FastAPI&lt;/a&gt; is a modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Sum up the basic documentation.&lt;/p&gt; &lt;p&gt;Explain how to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/#sending-data-to-the-server&#34;&gt;Sending data to the server&lt;/a&gt;: Through &lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/#path-parameters&#34;&gt;path parameters&lt;/a&gt;, &lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/#query-parameters&#34;&gt;query parameters&lt;/a&gt; and &lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/#body-requests&#34;&gt;body requests&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/#handling-errors&#34;&gt;Handle errors&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/#updating-data&#34;&gt;Update data&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/#openapi-configuration&#34;&gt;Configure OpenAPI&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/#testing&#34;&gt;Test FastAPI applications&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;And add a lot of &lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/#interesting-features-to-explore&#34;&gt;more interesting features&lt;/a&gt; I&#39;ve discovered.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/#logging-to-sentry&#34;&gt;Explain how to log exceptions to sentry.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/#sending-data-to-the-client&#34;&gt;Explain how to send raw data to the client.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;With the &lt;a href=&#34;https://fastapi.tiangolo.com/advanced/response-directly/#returning-a-custom-response&#34;&gt;&lt;code&gt;Response&lt;/code&gt;&lt;/a&gt; object.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/#configuration&#34;&gt;Explain how to configure the application.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/#inject-testing-configuration&#34;&gt;Explain how to inject a testing configuration in the tests.&lt;/a&gt;&lt;/li&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/#deploy-with-docker&#34;&gt;Explain how to deploy it using Docker.&lt;/a&gt;&lt;/li&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/#logging&#34;&gt;Explain how to show logging messages in the logs.&lt;/a&gt;&lt;/li&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/#create-redirections&#34;&gt;Explain how to make redirections with fastapi.&lt;/a&gt;&lt;/li&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/#run-a-fastapi-server-in-the-background-for-testing-purposes&#34;&gt;Explain how to run a FastAPI server in the background for testing purposes.&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Improvement: Add link to the Awesome FastAPI page.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;plugin-system&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/python_plugin_system/&#34;&gt;Plugin System&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add beets system as a first approach.&lt;/p&gt; &lt;p&gt;When building Python applications, it&#39;s good to develop the core of your program, and allow extension via plugins.&lt;/p&gt; &lt;p&gt;I still don&#39;t know how to do it, but &lt;a href=&#34;https://beets.readthedocs.io/en/stable/dev/plugins.html&#34;&gt;Beets plugin system&lt;/a&gt; looks awesome for a first start.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;flask-restplus&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/flask_restplus/&#34;&gt;Flask Restplus&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the Flask-RESTPlus library.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://flask-restplus.readthedocs.io/en/stable/&#34;&gt;Flask-RESTPlus&lt;/a&gt; is an extension for Flask that adds support for quickly building REST APIs, but I&#39;d use &lt;a href=&#34;https://lyz-code.github.io/blue-book/fastapi/&#34;&gt;FastAPI&lt;/a&gt; instead.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;optimization&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/python_optimization/&#34;&gt;Optimization&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/python_optimization/#tips&#34;&gt;Add tips on how to optimize your python command line tools.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;&lt;a href=&#34;#minimize-the-relative-import-statements-on-command-line-tools&#34;&gt;Minimize the relative import statements on command line tools&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;When developing a library, it&#39;s common to expose the main objects into the package &lt;code&gt;__init__.py&lt;/code&gt; under the variable &lt;code&gt;__all__&lt;/code&gt;. The problem with command line programs is that each time you run the command it will load those objects, which can mean an increase of 0.5s or even a second for each command, which is unacceptable. * &lt;a href=&#34;#dont-dynamically-install-the-package&#34;&gt;Don&#39;t dynamically install the package&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;If you install the package with &lt;code&gt;pip install -e .&lt;/code&gt; you will see an increase on the load time of ~0.2s. It is useful to develop the package, but when you use it, do so from a virtualenv that installs it directly without the &lt;code&gt;-e&lt;/code&gt; flag.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;gitpython&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/gitpython/&#34;&gt;GitPython&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the python library.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://gitpython.readthedocs.io&#34;&gt;GitPython&lt;/a&gt; is a python library used to interact with git repositories, high-level like git-porcelain, or low-level like git-plumbing.&lt;/p&gt; &lt;p&gt;It provides abstractions of git objects for easy access of repository data, and additionally allows you to access the git repository more directly using either a pure python implementation, or the faster, but more resource intensive git command implementation.&lt;/p&gt; &lt;p&gt;Explain how to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Initialize or load repositories.&lt;/li&gt; &lt;li&gt;Make commits.&lt;/li&gt; &lt;li&gt;Interact with the history.&lt;/li&gt; &lt;li&gt;Test applications that use it.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Explain how to get the working directory of a repo.&lt;/p&gt; &lt;p&gt;Using the &lt;code&gt;working_dir&lt;/code&gt; attribute.&lt;/p&gt; &lt;p&gt;perf(python_snippets#Group a list of dictionaries by a specific key) Explain how to group a list of dictionaries by a specific key&lt;/p&gt; &lt;p&gt;With &lt;code&gt;itertools.groupby&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/gitpython/#clone-a-repository&#34;&gt;Clone a repository.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;git&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Repo&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;Repo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;clone_from&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;git_url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;repo_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/gitpython/#create-a-branch&#34;&gt;Create a branch.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;new_branch&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;repo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;create_head&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;new_branch&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;repo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;active_branch&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new_branch&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# It&#39;s not checked out yet&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;repo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;head&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;reference&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new_branch&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;repo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;head&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_detached&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/gitpython/#get-the-latest-commit-of-a-repository&#34;&gt;Get the latest commit of a repository.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;repo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;head&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;object&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hexsha&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pytest&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pytest/&#34;&gt;Pytest&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pytest/#excluding-code-from-coverage&#34;&gt;Explain how to exclude code from the coverage report.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Add &lt;code&gt;# pragma: no cover&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pytest/#running-tests-in-parallel&#34;&gt;Explain how to run tests in parallel.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;pytest-xdist&lt;/code&gt; makes it possible to run the tests in parallel, useful when the test suit is large or when the tests are slow.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pytest-xdist
pytest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;auto
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pytest/#setting-a-timeout-for-your-tests&#34;&gt;Explain how to set a timeout for your tests.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Using &lt;a href=&#34;https://pypi.org/project/pytest-timeout/&#34;&gt;pytest-timeout&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pytest/#rerun-tests-that-fail-sometimes&#34;&gt;Explain how to rerun tests that fail sometimes.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;With &lt;a href=&#34;https://pypi.org/project/pytest-rerunfailures/&#34;&gt;pytest-rerunfailures&lt;/a&gt; that is a plugin for pytest that re-runs tests to eliminate intermittent failures. Using this plugin is generally a bad idea, it would be best to solve the reason why your code is not reliable. It&#39;s useful when you rely on non robust third party software in a way that you can&#39;t solve, or if the error is not in your code but in the testing code, and again you are not able to fix it.&lt;/p&gt; &lt;p&gt;feat(python_snippets#Create combination of elements in groups of two): Explain how to create combination of elements in groups of two&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;itertools&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;combinations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;ABC&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;[(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;A&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;B&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;A&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;C&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;B&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;C&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pytest/#excluding-code-from-coverage&#34;&gt;Exclude the &lt;code&gt;if TYPE_CHECKING&lt;/code&gt; code from the coverage.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you want &lt;a href=&#34;https://github.com/nedbat/coveragepy/issues/831&#34;&gt;other code to be excluded&lt;/a&gt;, for example the statements inside the &lt;code&gt;if TYPE_CHECKING:&lt;/code&gt; add to your &lt;code&gt;pyproject.toml&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[tool.coverage.report]&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;exclude_lines&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Have to re-enable the standard pragma&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;pragma: no cover&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Type checking can not be tested&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;if TYPE_CHECKING:&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce goodconf the pyndantic YAML friendly configuration management.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/lincolnloop/goodconf/&#34;&gt;goodconf&lt;/a&gt; is a thin wrapper over Pydantic&#39;s settings management. Allows you to define configuration variables and load them from environment or JSON/YAML file. Also generates initial configuration files and documentation for your defined configuration.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pytest/#capture-deprecation-warnings&#34;&gt;Capture deprecation warnings.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Python and its ecosystem does not have an assumption of strict SemVer, and has a tradition of providing deprecation warnings. If you have good CI, you should be able to catch warnings even before your users see them. Try the following pytest configuration:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[tool.pytest.ini_options]&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;filterwarnings&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;error&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This will turn warnings into errors and allow your CI to break before users break.&lt;/p&gt; &lt;p&gt;Other sections added are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pytest/#ensuring-code-triggers-a-deprecation-warning&#34;&gt;Ensuring code triggers a deprecation warning&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pytest/#asserting-warnings-with-the-warns-function&#34;&gt;Asserting warnings with the warns function&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pytest/#recording-warnings&#34;&gt;Recording warnings&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;python-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/&#34;&gt;Python Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;Correction: Explain how to show the message in custom exceptions.&lt;/li&gt; &lt;li&gt;New: Explain how to import a module or object from within a python program.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add today&#39;s learned python tricks.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-systems-timezone-and-use-it-in-datetime&#34;&gt;Get system&#39;s timezone and use it in datetime&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#capitalize-a-sentence&#34;&gt;Capitalize a sentence&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-the-last-monday-datetime&#34;&gt;Get the last monday datetime&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Explain how to use Jinja2.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://jinja.palletsprojects.com&#34;&gt;Jinja2&lt;/a&gt; is a modern and designer-friendly templating language for Python, modelled after Django’s templates. It is fast, widely used and secure with the optional sandboxed template execution environment.&lt;/p&gt; &lt;p&gt;Add installation, usage and basic and advanced template guidelines.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add date management snippets.&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-the-week-number-of-a-datetime&#34;&gt;Get the week number of a datetime&lt;/a&gt;: &lt;code&gt;datetime.datetime(2010, 6, 16).isocalendar()[1]&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-the-monday-of-a-week-number&#34;&gt;Get the Monday of a week number&lt;/a&gt;:&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;datetime&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;2013-W26&#34;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;strptime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;-1&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;%Y-W%W-%w&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-the-month-name-from-a-number&#34;&gt;Get the month name from a number&lt;/a&gt;:&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;calendar&lt;/span&gt;

&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;calendar&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;month_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;&#39;March&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; * &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-ordinal-from-number&#34;&gt;Get ordinal from number&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;int_to_ordinal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;number&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#39;&#39;&#39;Convert an integer into its ordinal representation.&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;    make_ordinal(0)   =&amp;gt; &#39;0th&#39;&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    make_ordinal(3)   =&amp;gt; &#39;3rd&#39;&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    make_ordinal(122) =&amp;gt; &#39;122nd&#39;&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    make_ordinal(213) =&amp;gt; &#39;213th&#39;&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;    Args:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        number: Number to convert&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;    Returns:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        ordinal representation of the number&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    &#39;&#39;&#39;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;suffix&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;th&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;st&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;nd&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;rd&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;th&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;][&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;min&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;number&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)]&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;11&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;number&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;13&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;suffix&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;th&#39;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;number&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;suffix&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add file management snippets.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#remove-the-extension-of-a-file&#34;&gt;Remove the extension of a file&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#iterate-over-the-files-of-a-directory&#34;&gt;Iterate over the files of a directory&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#create-directory&#34;&gt;Create directory&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#touch-a-file&#34;&gt;Touch a file&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-the-first-day-of-next-month&#34;&gt;Get the first day of next month.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#check-directories-and-files&#34;&gt;Explain how to test directories and files.&lt;/a&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#install-a-python-dependency-from-a-git-repository&#34;&gt;Explain how to install dependencies from git repositories.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;With &lt;a href=&#34;https://stackoverflow.com/questions/16584552/how-to-state-in-requirements-txt-a-direct-github-source&#34;&gt;pip you can&lt;/a&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;git+git://github.com/path/to/repository@master
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you want &lt;a href=&#34;https://stackoverflow.com/questions/32688688/how-to-write-setup-py-to-include-a-git-repository-as-a-dependency/54794506#54794506&#34;&gt;to hard code it in your &lt;code&gt;setup.py&lt;/code&gt;&lt;/a&gt;, you need to:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;install_requires&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
  &lt;span class=&#34;s1&#34;&gt;&#39;some-pkg @ git+ssh://git@github.com/someorgname/pkg-repo-name@v1.1#egg=some-pkg&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Explain how to create PyPI valid packages with direct dependencies.&lt;/p&gt; &lt;p&gt;It looks like PyPI don&#39;t want pip to reach out to URLs outside their site when installing from PyPI. So you can&#39;t define the direct dependencies in the &lt;code&gt;install_requires&lt;/code&gt;. Instead you need to install them in a &lt;code&gt;PostInstall&lt;/code&gt; custom script. Ugly as hell.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#install-a-python-dependency-from-a-git-repository&#34;&gt;Add warning about the method to use direct dependencies.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Last time I used this solution, when I added the library on a &lt;code&gt;setup.py&lt;/code&gt; the direct dependencies weren&#39;t installed :S&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#convert-html-to-readable-plaintext&#34;&gt;Explain how to convert html code to readable plaintext.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;html2text
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;html2text&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;html&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;foobar.html&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;html2text&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;html2text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;html&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#parse-a-datetime-from-a-string&#34;&gt;Explain how to parse a datetime from a string.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;dateutil&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Aug 28 1999 12:00AM&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# datetime.datetime(1999, 8, 28, 0, 0)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#find-a-static-file-of-a-python-module&#34;&gt;Explain how to find a static file of a python module.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pkg_resources&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;file_path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pkg_resources&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;resource_filename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;my_package&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;assets/config.yaml&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#delete-a-file&#34;&gt;Explain how to delete a file.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;remove&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;demofile.txt&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#measure-elapsed-time-between-lines-of-code&#34;&gt;Explain how to measure elapsed time between lines of code.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;time&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;start&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;hello&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;end&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;end&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#when-to-use-isinstance-and-when-to-use-type&#34;&gt;Document when to use &lt;code&gt;isinstance&lt;/code&gt; and when to use &lt;code&gt;type&lt;/code&gt;.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;isinstance&lt;/code&gt; takes into account inheritance, while &lt;code&gt;type&lt;/code&gt; doesn&#39;t. So if you want to make sure you&#39;re dealing with a specific class, and not any of it&#39;s parents or subclasses, use &lt;code&gt;type(obj) == class&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#check-if-a-dictionary-is-a-subset-of-another&#34;&gt;Check if a dictionary is a subset of another.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you have two dictionaries &lt;code&gt;big = {&#39;a&#39;: 1, &#39;b&#39;: 2, &#39;c&#39;:3}&lt;/code&gt; and &lt;code&gt;small = {&#39;c&#39;: 3, &#39;a&#39;: 1}&lt;/code&gt;, and want to check whether &lt;code&gt;small&lt;/code&gt; is a subset of &lt;code&gt;big&lt;/code&gt;, use the next snippet:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;small&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;items&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;big&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;items&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#group-or-sort-a-list-of-dictionaries-or-objects-by-a-specific-key&#34;&gt;Group or sort a list of dictionaries or objects by a specific key.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Improve previous method with the concepts learned from the &lt;a href=&#34;https://docs.python.org/3/howto/sorting.html#sorting-basics&#34;&gt;official docs&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Particularly improve the sorting by multiple keys with the next function:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;multisort&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;specs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;reverse&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;reversed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;specs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;xs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sort&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;attrgetter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;reverse&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;reverse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;xs&lt;/span&gt;

&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;multisort&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;student_objects&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;grade&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;age&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;[(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;dave&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;B&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;jane&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;B&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;john&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;A&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#install-default-directories-and-files-for-a-command-line-program&#34;&gt;Install default directories and files for a command line program.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I&#39;ve been trying for a long time to configure &lt;code&gt;setup.py&lt;/code&gt; to run the required steps to configure the required directories and files when doing &lt;code&gt;pip install&lt;/code&gt; without success.&lt;/p&gt; &lt;p&gt;Finally, I decided that the program itself should create the data once the &lt;code&gt;FileNotFoundError&lt;/code&gt; exception is found. That way, you don&#39;t penalize the load time because if the file or directory exists, that code is not run.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#locate-element-in-list&#34;&gt;Locate element in list.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;a&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;b&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;index&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;b&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#transpose-a-list-of-lists&#34;&gt;Transpose a list of lists.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;l&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;9&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;zip&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;l&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)]&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;9&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#check-the-type-of-a-list-of-strings&#34;&gt;Check the type of a list of strings.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;_is_list_of_lists&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Any&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Check if data is a list of strings.&#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;all&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;elem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;elem&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#replace-all-characters-of-a-string-with-another-character&#34;&gt;Replace all characters of a string with another character.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;mystring&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;_&#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mystring&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#make-a-flat-list-of-lists-with-a-list-comprehension&#34;&gt;Make a flat list of lists with a list comprehension.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;There is no nice way to do it :(. The best I&#39;ve found is:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;t&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;9&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;flat_list&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;item&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sublist&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;t&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;item&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sublist&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#remove-a-substring-from-the-end-of-a-string&#34;&gt;Remove a substring from the end of a string.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;On Python 3.9 and newer you can use the &lt;code&gt;removeprefix&lt;/code&gt; and &lt;code&gt;removesuffix&lt;/code&gt; methods to remove an entire substring from either side of the string:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;url&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;abcdc.com&#39;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;removesuffix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;.com&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;# Returns &#39;abcdc&#39;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;removeprefix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;abcdc.&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# Returns &#39;com&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;On Python 3.8 and older you can use &lt;code&gt;endswith&lt;/code&gt; and slicing:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;url&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;abcdc.com&#39;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;endswith&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;.com&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;url&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[:&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#capture-the-stdout-of-a-function&#34;&gt;Capture the stdout of a function.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;io&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;contextlib&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;redirect_stdout&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;io&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;StringIO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;redirect_stdout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;do_something&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;my_object&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;out&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getvalue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#make-temporal-directory&#34;&gt;Make temporal directory.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;tempfile&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;dirpath&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tempfile&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mkdtemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#change-the-working-directory-of-a-test&#34;&gt;Change the working directory of a test.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;unittest&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;

&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;src.main&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;get_cwd&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;TestMain&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;unittest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TestCase&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;test_get_cwd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;src&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;testing get_cwd()&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;current_dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;get_cwd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;assertIsNotNone&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;assertEqual&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;src&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#copy-a-directory&#34;&gt;Copy a directory.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;shutil&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;shutil&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;copytree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;bar&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;foo&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#change-the-working-directory-of-a-test&#34;&gt;Use fixture to change the working directory of a test.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The previous code didn&#39;t work, instead use the next fixture:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nd&#34;&gt;@pytest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fixture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;change_test_dir&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;change_test_dir_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SubRequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Any&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fspath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dirname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;yield&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;invocation_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#ipv4-regular-expression&#34;&gt;IPv4 regular expression.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;regex&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;re&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;compile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
    &lt;span class=&#34;sa&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;(?&amp;lt;![-\.\d])(?:0{0,2}?[0-9]\.|1\d?\d?\.|2[0-5]?[0-5]?\.)&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{3}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
    &lt;span class=&#34;sa&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;(?:0{0,2}?[0-9]|1\d?\d?|2[0-5]?[0-5]?)(?![\.\d])&#34;^[0-9]{1,3}*$&#39;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#remove-the-elements-of-a-list-from-another&#34;&gt;Remove the elements of a list from another.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#change-the-logging-level-of-a-library&#34;&gt;Change the logging level of a library.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;sh_logger&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getLogger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;sh&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;sh_logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setLevel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WARN&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-all-subdirectories-of-a-directory&#34;&gt;Get all subdirectories of a directory.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;walk&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#move-a-file&#34;&gt;Move a file.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;path/to/current/file.foo&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;path/to/new/destination/for/file.foo&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#copy-a-file&#34;&gt;Copy a file.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;shutil&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;shutil&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;copyfile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dest_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;mkdocstrings&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/docstrings/&#34;&gt;mkdocstrings&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: How to write good test docstrings.&lt;/p&gt; &lt;p&gt;Both &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/docstrings/#without-template&#34;&gt;without a template&lt;/a&gt; and using the &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/docstrings/#given-when-then&#34;&gt;Given When Then style&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;networkx&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/networkx/&#34;&gt;NetworkX&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the python library.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://networkx.org/&#34;&gt;NetworkX&lt;/a&gt; is a Python package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pexpect&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/pexpect/&#34;&gt;pexpect&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the pexpect python library.&lt;/p&gt; &lt;p&gt;A pure Python module for spawning child applications; controlling them; and responding to expected patterns in their output. Pexpect works like Don Libes’ Expect. Pexpect allows your script to spawn a child application and control it as if a human were typing commands.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/pexpect/#read-output-of-command&#34;&gt;Explain how to read the output of a command run by pexpect.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;sys&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pexpect&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;child&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pexpect&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;spawn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;ls&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;child&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logfile&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stdout&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;child&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;expect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pexpect&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EOF&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;prompt-toolkit&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/prompt_toolkit/&#34;&gt;Prompt Toolkit&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the tui python library.&lt;/p&gt; &lt;p&gt;Useful to build text-based user interfaces, it allows the creation of intelligent prompts, dialogs, and full screen ncurses-like applications.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/prompt_toolkit/#full-screen-applications&#34;&gt;Basic concepts of building full screen applications with python prompt toolkit.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;prompt_toolkit&lt;/code&gt; can be used to create complex full screen terminal applications. Typically, an application consists of a layout (to describe the graphical part) and a set of key bindings.&lt;/p&gt; &lt;p&gt;In the section we cover:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/prompt_toolkit/#the-layout&#34;&gt;The layout&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/prompt_toolkit/#the-controls&#34;&gt;The controls&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/prompt_toolkit/#key-bindings&#34;&gt;How to use key bindings&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/prompt_toolkit/#styles&#34;&gt;How to apply styles&lt;/a&gt;&lt;/li&gt; &lt;li&gt;A difficult ordered list of &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/prompt_toolkit/#examples&#34;&gt;examples&lt;/a&gt; to get a grasp of these concepts with simple working code.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pydantic&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pydantic/&#34;&gt;Pydantic&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Explain how to initialize attributes.&lt;/p&gt; &lt;p&gt;Use validators to initialize attributes&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Name the pros and cons of using the library.&lt;/p&gt; &lt;/li&gt; &lt;li&gt;New: Explain how to create bidirectional relationship between entities.&lt;/li&gt; &lt;li&gt;New: Warn on the lack of TypeDict support.&lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: How to solve the No name &#39;BaseModel&#39; in module &#39;pydantic&#39;.&lt;/p&gt; &lt;p&gt;It&#39;s still a patch, so I&#39;ve also monitored the relevant &lt;a href=&#34;https://lyz-code.github.io/blue-book/issues/#pydantic-errors&#34;&gt;issues&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Change parse_obj definition to find how to import pydantic models from dictionary.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pydantic/#set-private-attributes&#34;&gt;Explain how to use private attributes.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;With the &lt;a href=&#34;https://pydantic-docs.helpmanual.io/usage/models/#private-model-attributes&#34;&gt;&lt;code&gt;PrivateAttr&lt;/code&gt;&lt;/a&gt; object.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pydantic/#update-entity-attributes-with-a-dictionary&#34;&gt;Explain how to update entity attributes with a dictionary.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can create a new object with the new data using the &lt;code&gt;update&lt;/code&gt; argument of the &lt;code&gt;copy&lt;/code&gt; entity method.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pydantic/#copy-produces-copy-that-modifies-the-original&#34;&gt;Copy produces copy that modifies the original.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;When copying a model, changing the value of an attribute on the copy updates the value of the attribute on the original. This only happens if &lt;code&gt;deep != True&lt;/code&gt;. To fix it use: &lt;code&gt;model.copy(deep=True)&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pydantic/#define-fields-to-exclude-from-exporting-at-config-level&#34;&gt;Define fields to exclude from exporting at config level.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Eagerly waiting for the release of the version 1.9 because you can &lt;a href=&#34;https://github.com/samuelcolvin/pydantic/issues/660&#34;&gt;define the fields to exclude in the &lt;code&gt;Config&lt;/code&gt; of the model&lt;/a&gt; using something like:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;User&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BaseModel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;username&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;password&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Transaction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BaseModel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;User&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;fields&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
            &lt;span class=&#34;s1&#34;&gt;&#39;value&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
                &lt;span class=&#34;s1&#34;&gt;&#39;alias&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;Amount&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                &lt;span class=&#34;s1&#34;&gt;&#39;exclude&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
            &lt;span class=&#34;s1&#34;&gt;&#39;user&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
                &lt;span class=&#34;s1&#34;&gt;&#39;exclude&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;username&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;password&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
            &lt;span class=&#34;s1&#34;&gt;&#39;id&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
                &lt;span class=&#34;s1&#34;&gt;&#39;dump_alias&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;external_id&#39;&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The release it&#39;s taking its time because &lt;a href=&#34;https://github.com/samuelcolvin/pydantic/discussions/3228&#34;&gt;the developer&#39;s gremlin and salaried work are sucking his time off&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pydantic/#field-customization&#34;&gt;Field customization.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Optionally, the &lt;code&gt;Field&lt;/code&gt; function can be used to provide extra information about the field and validations. Such as the &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;default&lt;/code&gt;, &lt;code&gt;description&lt;/code&gt; and many others&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pypika&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pypika/&#34;&gt;Pypika&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Explain how to insert, update, select data.&lt;/li&gt; &lt;li&gt;New: Explain how to join tables.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;python-mysql&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/sql/sql/&#34;&gt;Python Mysql&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Give examples on joins for each relationship type.&lt;/li&gt; &lt;li&gt;New: Explain how to interact with MySQL databases with Python.&lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Correct the syntax of the left joins.&lt;/p&gt; &lt;p&gt;Instead of using &lt;code&gt;ON users.id == addresses.user_id&lt;/code&gt;, use &lt;code&gt;ON users.id = addresses.user_id&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;questionary&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/questionary/&#34;&gt;questionary&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce tui python library.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://questionary.readthedocs.io&#34;&gt;questionary&lt;/a&gt; is a Python library for effortlessly building pretty command line interfaces. It makes it very easy to query your user for input.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Correct the link to the examples.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/questionary/#conditionally-skip-questions&#34;&gt;Conditionally skip questions.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Sometimes it is helpful to be able to skip a question based on a condition. To avoid the need for an if around the question, you can pass the condition when you create the question:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;questionary&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;DISABLED&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;questionary&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;confirm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Are you amazed?&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;skip_if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DISABLED&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ask&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/questionary/#don&#39;t-highlight-the-selected-option-by-default&#34;&gt;Don&#39;t highlight the selected option by default.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you don&#39;t want to highlight the default choice in the &lt;code&gt;select&lt;/code&gt; question use the next style:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;questionary&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Style&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;choice&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;select&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;Question title: &#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;choices&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;a&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;b&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;c&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;a&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;style&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Style&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;selected&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;noreverse&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)]),&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ask&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;rich&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/rich/&#34;&gt;rich&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the python cli builder library and it&#39;s progress bar.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/willmcgugan/rich&#34;&gt;Rich&lt;/a&gt; is a Python library for rich text and beautiful formatting in the terminal.&lt;/p&gt; &lt;p&gt;Check out the beautiful progress bar:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rich
python&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-m&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rich.progress
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/rich/#tables&#34;&gt;Explain how to build pretty tables with rich.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;rich.console&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Console&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;rich.table&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Table&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;table&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Table&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Star Wars Movies&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;table&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_column&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Released&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;justify&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;right&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;style&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;cyan&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;no_wrap&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;table&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_column&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Title&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;style&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;magenta&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;table&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_column&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Box Office&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;justify&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;right&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;style&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;green&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;table&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_row&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Dec 20, 2019&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Star Wars: The Rise of Skywalker&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;$952,110,690&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;table&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_row&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;May 25, 2018&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Solo: A Star Wars Story&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;$393,151,347&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;table&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_row&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Dec 15, 2017&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Star Wars Ep. V111: The Last Jedi&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;$1,332,539,889&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;table&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_row&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Dec 16, 2016&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Rogue One: A Star Wars Story&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;$1,332,439,889&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;console&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;table&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/rich/#rich-text&#34;&gt;Explain how to print pretty text with rich.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;rich.console&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Console&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;rich.text&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Text&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;console&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;text&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Text&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;assemble&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Hello&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;bold magenta&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34; World!&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;ruamel-yaml&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/ruamel_yaml/&#34;&gt;Ruamel YAML&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Improvement: Suggest to use ruyaml instead of ruamel.yaml.&lt;/p&gt; &lt;p&gt;As it&#39;s maintained by the community and versioned with git.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;selenium&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/selenium/&#34;&gt;Selenium&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Explain how to use selenium with python.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/selenium/#set-timeout-of-a-response&#34;&gt;Explain how to Set timeout of a response.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;driver&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set_page_load_timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;30&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/selenium/#chromedriver-hangs-up-unexpectedly&#34;&gt;Explain how to fix when Chromedriver hangs up unexpectedly.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;environ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;DBUS_SESSION_BUS_ADDRESS&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;/dev/null&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;sqlite3&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/sqlite3/&#34;&gt;sqlite3&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/sqlite3/#regexp&#34;&gt;Explain how to implement the REGEXP operator with Python.&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;requests&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/requests/&#34;&gt;Requests&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Introduce the requests python library.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;rq&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/rq/&#34;&gt;Rq&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add note to test arq.&lt;/p&gt; &lt;p&gt;arq is a similar library that can be better.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;tenacity&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/tenacity/&#34;&gt;Tenacity&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the Tenacity python library.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/jd/tenacity&#34;&gt;Tenacity&lt;/a&gt; is an Apache 2.0 licensed general-purpose retrying library, written in Python, to simplify the task of adding retry behavior to just about anything.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;tinydb&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/tinydb/&#34;&gt;TinyDB&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/tinydb/#serializing-custom-data&#34;&gt;Explain how to serialize datetime objects.&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;sqlite&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/sqlite/&#34;&gt;SQLite&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;New: Solve the autoincrementation not working bug.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/sqlite/#regexp&#34;&gt;Explain how to configure sqlite to be able to use the REGEXP operator.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It&#39;s not enabled by default.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Add rqlite as an interesting distributed solution of.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/sqlite/#get-the-columns-of-a-database&#34;&gt;Get the columns of a database.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;PRAGMA table_info(table_name);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;promql&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/promql/promql/&#34;&gt;Promql&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/promql/promql/#generating-range-vectors-from-return-values-in-prometheus-queries&#34;&gt;Generating range vectors from return values in Prometheus queries.&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;javascript&#34;&gt;Javascript&lt;/h3&gt; &lt;h4 id=&#34;mermaidjs&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/mermaidjs/&#34;&gt;MermaidJS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the diagram library and how to make flowchart diagrams.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://mermaid-js.github.io&#34;&gt;MermaidJS&lt;/a&gt; is a Javascript library that lets you create diagrams using text and code.&lt;/p&gt; &lt;p&gt;It can render the &lt;a href=&#34;https://mermaid-js.github.io/mermaid/#/?id=diagrams-that-mermaid-can-render&#34;&gt;next diagram types&lt;/a&gt;:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Flowchart&lt;/li&gt; &lt;li&gt;Sequence.&lt;/li&gt; &lt;li&gt;Gantt&lt;/li&gt; &lt;li&gt;Class&lt;/li&gt; &lt;li&gt;Git graph&lt;/li&gt; &lt;li&gt;Entity Relationship&lt;/li&gt; &lt;li&gt;User journey&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;issues&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/issues/&#34;&gt;Issues&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the issue tracking document.&lt;/p&gt; &lt;p&gt;I haven&#39;t found a tool to monitor the context it made me track certain software issues, so I get lost when updates come. Until a tool shows up, I&#39;ll use the good old markdown to keep track of them.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add today&#39;s issues.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Gadgetbridge improvements&lt;/li&gt; &lt;li&gt;Ombi improvements&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Monitor today&#39;s issues.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Mkdocs migration to 7.x is giving errors with the search bar and repo stats.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Track python dependency errors.&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Correction: Gitdb has updated smmap.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Jellyfin 10.7.1 broke the login page.&lt;/p&gt; &lt;p&gt;Don&#39;t upgrade till it&#39;s solved, as the rollback is not easy.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Jellyfin login page problem after upgrade to 10.7.X is solved.&lt;/p&gt; &lt;p&gt;Surprisingly the instructions in &lt;a href=&#34;https://github.com/jellyfin/jellyfin/issues/5489&#34;&gt;#5489&lt;/a&gt; solved it.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;stop&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;jellyfin.service
mv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/jellyfin/data/jellyfin.db&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;,.bak&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;start&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;jellyfin.service

&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Go&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;to&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;JF&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;URL,&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;asked&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;to&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;even&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;though&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;there&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;are&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;no&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Users&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;the&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;JF&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;DB&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;now&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;

systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;stop&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;jellyfin.service
mv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/jellyfin/data/jellyfin.db&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;.bak,&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;start&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;jellyfin.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;devops&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/devops/&#34;&gt;DevOps&lt;/a&gt;&lt;/h2&gt; &lt;ul&gt; &lt;li&gt;New: Comment on the DevOps pitfalls and update the learn path.&lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;infrastructure-as-code&#34;&gt;Infrastructure as Code&lt;/h3&gt; &lt;h4 id=&#34;helmfile&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/helmfile/&#34;&gt;Helmfile&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/helmfile/#keep-charts-updated&#34;&gt;Improve the helmfile chart update process.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Updating charts with &lt;code&gt;helmfile&lt;/code&gt; is easy as long as you don&#39;t use environments, you run &lt;code&gt;helmfile deps&lt;/code&gt;, then &lt;code&gt;helmfile diff&lt;/code&gt; and finally &lt;code&gt;helmfile apply&lt;/code&gt;. The tricky business comes when you want to use environments to reuse your helmfile code and don&#39;t repeat yourself. I&#39;ve updated the process to include this case.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/helmfile/#multi-environment-project-structure&#34;&gt;Document the directory and files structure for multi-environment projects.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/helmfile/#using-helmfile-environments&#34;&gt;Document how to use helmfile environments to follow DRY.&lt;/a&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/helmfile/#avoiding-code-repetition&#34;&gt;Document how to avoiding code repetition.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Besides environments, &lt;code&gt;helmfile&lt;/code&gt; gives other useful tricks to prevent the illness of code repetition, such as &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/helmfile/#using-release-templates&#34;&gt;using release templates&lt;/a&gt;, or &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/helmfile/#layering-the-state&#34;&gt;layering the state&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/helmfile/#managing-dependencies&#34;&gt;Document how to manage dependencies between the charts, to be able to use concurrency.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Helmfile support concurrency with the option &lt;code&gt;--concurrency=N&lt;/code&gt; so we can take advantage of it and improve our deployment speed, but to ensure it works as expected we have to define the dependencies among charts. For example, if an application needs a database, it has to be deployed before hand.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Use environment name instead of get values.&lt;/p&gt; &lt;p&gt;Instead of &lt;code&gt;.Environment.Name&lt;/code&gt;, in theory you could have used &lt;code&gt;.Vars | get &#34;environment&#34;&lt;/code&gt;, which could have prevented the variables and secrets of the default environment will need to be called &lt;code&gt;default_values.yaml&lt;/code&gt;, and &lt;code&gt;default_secrets.yaml&lt;/code&gt;, which is misleading. But you can&#39;t use &lt;code&gt;.Values&lt;/code&gt; in the &lt;code&gt;helmfile.yaml&lt;/code&gt; as it&#39;s not loaded when the file is parsed, and you get an error. A solution would be to &lt;a href=&#34;https://github.com/roboll/helmfile/blob/8594944f6374454e6ddea61d04b201133798cd95/docs/writing-helmfile.md#layering-state-template-files&#34;&gt;layer the helmfile state files&lt;/a&gt; but I wasn&#39;t able to make it work.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: How to install a chart only in one environment.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;environments&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;production&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;

&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;releases&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;newrelic-agent&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;installed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;eq .Environment.Name &#34;production&#34; | toYaml&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;}}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# snip&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add note that templates can&#39;t be used inside the secrets.&lt;/p&gt; &lt;p&gt;See &lt;a href=&#34;https://github.com/jkroepke/helm-secrets/issues/126&#34;&gt;this issue&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;terraform&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/terraform/&#34;&gt;Terraform&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce terraform and how to handle RDS secrets.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Terraform_(software)&#34;&gt;Terraform&lt;/a&gt; is an open-source infrastructure as code software tool created by HashiCorp. It enables users to define and provision a datacenter infrastructure using an awful high-level configuration language known as Hashicorp Configuration Language (HCL), or optionally JSON. Terraform supports a number of cloud infrastructure providers such as Amazon Web Services, IBM Cloud , Google Cloud Platform, DigitalOcean, Linode, Microsoft Azure, Oracle Cloud Infrastructure, OVH, or VMware vSphere as well as OpenNebula and OpenStack.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/terraform/#ignore-the-change-of-an-attribute&#34;&gt;Explain how to ignore the change of an attribute.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;resource&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;&#34;aws_instance&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&#34;example&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;  # ...&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;lifecycle&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;ignore_changes&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;      # Ignore changes to tags, e.g. because a management agent&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;      # updates these based on some ruleset managed elsewhere.&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;tags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/terraform/#define-the-default-value-of-an-variable-that-contains-an-object-as-empty&#34;&gt;Explain how to define the default value of an variable that contains an object as empty.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;variable&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&#34;database&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;object&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                 &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;number&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;instance_type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;storage_type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;engine&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;               &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;engine_version&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;parameter_group_name&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;multi_az&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;null&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/terraform/#do-a-conditional-if-a-variable-is-not-null&#34;&gt;Explain how to do a conditional if a variable is not null.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;resource&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;&#34;aws_db_instance&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;&#34;instance&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;var.database&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/terraform/#conditionals&#34;&gt;How to do elif conditionals in terraform.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;locals&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;test&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;${ condition ? value : (elif-condition ? elif-value : else-value)}&#34;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/terraform/#debugging&#34;&gt;How to enable debug traces.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can set the &lt;code&gt;TF_LOG&lt;/code&gt; environmental variable to one of the log levels &lt;code&gt;TRACE&lt;/code&gt;, &lt;code&gt;DEBUG&lt;/code&gt;, &lt;code&gt;INFO&lt;/code&gt;, &lt;code&gt;WARN&lt;/code&gt; or &lt;code&gt;ERROR&lt;/code&gt; to change the verbosity of the logs.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;helm-secrets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/helm/helm_secrets/&#34;&gt;Helm Secrets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Update the repository url.&lt;/p&gt; &lt;p&gt;The last fork is dead, long live the &lt;a href=&#34;https://github.com/jkroepke/helm-secrets&#34;&gt;fork&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: How to install the plugin.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;helm-git&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/helm_git/&#34;&gt;Helm Git&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Suggest version 0.8.0 until issue is solved.&lt;/p&gt; &lt;p&gt;Newer versions have a &lt;a href=&#34;https://github.com/aslafy-z/helm-git/issues/131&#34;&gt;bug&lt;/a&gt; that makes impossible to use helm_git with a repository that contains just one chart in the root of the git repository.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Update installation method.&lt;/p&gt; &lt;p&gt;In the last version 0.11.1, the issue that forced us to use the version 0.8.0 was solved&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;infrastructure-solutions&#34;&gt;Infrastructure Solutions&lt;/h3&gt; &lt;h4 id=&#34;kubernetes&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes/&#34;&gt;Kubernetes&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes/#tools-to-test&#34;&gt;Add Velero as interesting tool.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://velero.io/&#34;&gt;Velero&lt;/a&gt; is a tool to backup and migrate Kubernetes resources and persistent volumes.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;architecture&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes_architecture/&#34;&gt;Architecture&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes_architecture/#number-of-clusters&#34;&gt;Give suggestions on how to choose the number of kubernetes clusters to use.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can run a given set of workloads either on few large clusters (with many workloads in each cluster) or on many clusters (with few workloads in each cluster).&lt;/p&gt; &lt;p&gt;Here&#39;s a table that summarizes the pros and cons of various approaches:&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34; &#34; src=&#34;../../img/number_k8s_clusters.svg&#34;/&gt; &lt;em&gt;Figure: Possibilities of number of clusters from &lt;a href=&#34;https://learnk8s.io/how-many-clusters&#34;&gt;learnk8s.io article&lt;/a&gt;&lt;/em&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;jobs&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes_jobs/&#34;&gt;Jobs&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Improvement: Remove false positive alerts on failed jobs that succeeded.&lt;/p&gt; &lt;p&gt;A Kubernetes cronjob spawns jobs, if the first one fails, it will try to spawn a new one. If the second succeeds, the cronjob status should be success, but with the rule we had before, a successful job with failed past jobs will still raise an alert.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes_jobs/#rerunning-failed-jobs&#34;&gt;Explain how to rerun failed cronjobs.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you have a job that has failed after the 6 default retries, it will show up in your monitorization forever, to fix it, you can manually trigger the job.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;job&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;your-job&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;json&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;jq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;del(.spec.selector)&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;jq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;del(.spec.template.metadata.labels)&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;replace&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--force&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes_jobs/#manually-creating-a-job-from-a-cronjob&#34;&gt;Manually creating a job from a cronjob.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;create&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;job&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;job_name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;namespace&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;--from&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;cronjobs/&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cronjob_name&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;continuous-integration&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/ci/&#34;&gt;Continuous Integration&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Explain how to troubleshoot the error: pathspec master did not match any file.&lt;/p&gt; &lt;p&gt;Remove all git hooks with &lt;code&gt;rm -r .git/hooks&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;flakehell&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/bandit/&#34;&gt;Flakehell&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Explain how to ignore errors.&lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Update the git repository.&lt;/p&gt; &lt;p&gt;The existent repository has been archived in favor of &lt;a href=&#34;https://github.com/flakeheaven/flakeheaven&#34;&gt;this one&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Explain how to patch the extended_default_ignore error for versions &amp;gt; 3.9.0.&lt;/p&gt; &lt;p&gt;Add to your your &lt;code&gt;pyproject.toml&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[tool.flakeheaven]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;extended_default_ignore&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# add this&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/flakeheaven/#troubleshooting&#34;&gt;Troubleshoot the &#39;Namespace&#39; object has no attribute &#39;extended_default_ignore&#39; error.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Add to your &lt;code&gt;pyproject.toml&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[tool.flakeheaven]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;extended_default_ignore&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/flakeheaven/#issues&#34;&gt;Latest version is broken.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It returns an &lt;a href=&#34;https://github.com/flakeheaven/flakeheaven/issues/22&#34;&gt;ImportError: cannot import name &#39;MergedConfigParser&#39; from &#39;flake8.options.config&#39;&lt;/a&gt;, wait for the issue to be solved before upgrading.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pyment&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/pyment/&#34;&gt;Pyment&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Pyment.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/dadadel/pyment&#34;&gt;Pyment&lt;/a&gt; is a python3 program to automatically create, update or convert docstrings in existing Python files, managing several styles.&lt;/p&gt; &lt;p&gt;As of 2021-11-17, the program is not production ready yet for me, I&#39;ve tested it in one of my projects and found some bugs that needed to be fixed before it&#39;s usable. Despite the number of stars, it looks like the development pace has dropped dramatically, so it needs our help to get better :).&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;dependency-managers&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/pip_tools/&#34;&gt;Dependency managers&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Sync the virtualenv libraries with the requirements files.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;python&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;piptools&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sync&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;requirements&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txt&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;requirements&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dev&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;txt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Use &lt;code&gt;-c&lt;/code&gt; instead of &lt;code&gt;-r&lt;/code&gt; in the nested requirement files.&lt;/p&gt; &lt;p&gt;To avoid duplication of version pins.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Deprecate in favour of Poetry.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;automating-processes&#34;&gt;Automating Processes&lt;/h3&gt; &lt;h4 id=&#34;cruft&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/cruft/&#34;&gt;cruft&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/cruft/#issues&#34;&gt;Monitor the issue to save the cruft config in &lt;code&gt;pyproject.toml&lt;/code&gt;.&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;monitoring&#34;&gt;Monitoring&lt;/h3&gt; &lt;h4 id=&#34;monitoring-comparison&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/monitoring_comparison/&#34;&gt;Monitoring Comparison&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Compare Nagios and Prometheus as monitoring.&lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Improve the comparison.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;State that nagios is not easy to configure. If you&#39;re used to it it is, otherwise it&#39;s not.&lt;/li&gt; &lt;li&gt;Add that grafana has a huge community building graphs.&lt;/li&gt; &lt;li&gt;Mention Thanos as the long term storage solution for Prometheus.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Add the insights of a nagios power user.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Update open source and community analysis with nagios exchange.&lt;/li&gt; &lt;li&gt;Correct nagios community analysis with its trajectory&lt;/li&gt; &lt;li&gt;Correct the analysis of the high availability of nagios&lt;/li&gt; &lt;li&gt;Add the option to host the script exporter in a dedicated server&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;prometheus-install&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/prometheus_installation/&#34;&gt;Prometheus Install&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Add warning that helm 2 support is dropped.&lt;/p&gt; &lt;p&gt;If you want to use the helm chart above 11.1.7 you need to use helm 3.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/prometheus_installation/#upgrading-notes&#34;&gt;Add upgrading notes from 10.x -&amp;gt; 11.1.7.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;admonition warning&#34;&gt; &lt;p class=&#34;admonition-title&#34;&gt;Don&#39;t upgrade to 12.x if you&#39;re still using Helm 2.&lt;/p&gt; &lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;elasticsearch-exporter&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/elasticsearch_exporter/&#34;&gt;Elasticsearch Exporter&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the prometheus elasticsearch exporter.&lt;/p&gt; &lt;p&gt;The &lt;a href=&#34;https://github.com/prometheus-community/elasticsearch_exporter&#34;&gt;elasticsearch exporter&lt;/a&gt; allows monitoring &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/elasticsearch/&#34;&gt;Elasticsearch&lt;/a&gt; clusters with &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/prometheus/&#34;&gt;Prometheus&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Explain how to install it, configure the grafana dashboards and the alerts.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Add more elasticsearch alerts.&lt;/p&gt; &lt;p&gt;Measure the search latency, search rate and create alerts on the garbage collector, json parser and circuit breaker errors&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add alert on low number of healthy master nodes.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;scrum&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/scrum/&#34;&gt;Scrum&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the scrum framework.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Scrum_%28software_development%29&#34;&gt;Scrum&lt;/a&gt; is an &lt;a href=&#34;https://en.wikipedia.org/wiki/Agile_software_development&#34;&gt;agile&lt;/a&gt; framework for developing, delivering, and sustaining complex products, with an initial emphasis on software development, although it has been used in other fields such as personal task management. It is designed for teams of ten or fewer members, who break their work into goals that can be completed within time-boxed iterations, called sprints, no longer than one month and most commonly two weeks. The Scrum Team track progress in 15-minute time-boxed daily meetings, called daily scrums. At the end of the sprint, the team holds sprint review, to demonstrate the work done, a sprint retrospective to improve continuously, and a sprint planning to prepare next sprint&#39;s tasks.&lt;/p&gt; &lt;p&gt;In the article I explain:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;I use to do &lt;a href=&#34;https://lyz-code.github.io/blue-book/scrum/#the-meetings&#34;&gt;the meetings&lt;/a&gt;: &lt;a href=&#34;https://lyz-code.github.io/blue-book/scrum/#daily-meetings&#34;&gt;Daily&lt;/a&gt;, &lt;a href=&#34;https://lyz-code.github.io/blue-book/scrum/#refinement-meetings&#34;&gt;Refinement&lt;/a&gt;, &lt;a href=&#34;https://lyz-code.github.io/blue-book/scrum/#retro-meetings&#34;&gt;Retros&lt;/a&gt;, &lt;a href=&#34;https://lyz-code.github.io/blue-book/scrum/#review-meetings&#34;&gt;Reviews&lt;/a&gt; and &lt;a href=&#34;https://lyz-code.github.io/blue-book/scrum/#planning-meetings&#34;&gt;Plannings&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;The relevant &lt;a href=&#34;https://lyz-code.github.io/blue-book/scrum/#the-roles&#34;&gt;roles&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;Some &lt;a href=&#34;https://lyz-code.github.io/blue-book/scrum/#definitions&#34;&gt;definitions&lt;/a&gt;, such as definition of done and definition of ready.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;software-architecture&#34;&gt;Software Architecture&lt;/h2&gt; &lt;h3 id=&#34;domain-driven-design&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/architecture/domain_driven_design/&#34;&gt;Domain Driven Design&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Improvement: Add warning when migrating old code.&lt;/p&gt; &lt;p&gt;You may be tempted to migrate all your old code to this architecture once you fall in love with it. Truth being told, it&#39;s the best way to learn how to use it, but it&#39;s time expensive too! &lt;a href=&#34;https://github.com/lyz-code/clinv/pull/40&#34;&gt;The last refactor&lt;/a&gt; I did required a change of 60% of the code. The upside is that I reduced the total lines of code a 25%.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;architecture-decision-record&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/adr/&#34;&gt;Architecture Decision Record&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the Architecture Decision Records.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/joelparkerhenderson/architecture_decision_record&#34;&gt;ADR&lt;/a&gt; are short text documents that captures an important architectural decision made along with its context and consequences.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/adr/#adr-template&#34;&gt;Update the ADR template with the week learnings.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Add the Proposals and Date sections&lt;/li&gt; &lt;li&gt;Explain the possible Status states.&lt;/li&gt; &lt;li&gt;Add an &lt;a href=&#34;https://github.com/SirVer/ultisnips&#34;&gt;Ultisnip&lt;/a&gt; vim snippet.&lt;/li&gt; &lt;li&gt;Explain how I&#39;ve used it to create &lt;a href=&#34;https://github.com/lyz-code/mkdocs-newsletter&#34;&gt;mkdocs-newsletter&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Explain how to show relationship between ADRs.&lt;/p&gt; &lt;p&gt;Suggest a &lt;a href=&#34;https://lyz-code.github.io/blue-book/mermaidjs/&#34;&gt;mermaidjs&lt;/a&gt; diagram to show the state of the project ADRs.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;operative-systems&#34;&gt;Operative Systems&lt;/h2&gt; &lt;h3 id=&#34;linux&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/tahoe/&#34;&gt;Linux&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Tahoe-LAFS.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Tahoe-LAFS&#34;&gt;Tahoe-LAFS&lt;/a&gt; is a free and open, secure, decentralized, fault-tolerant, distributed data store and distributed file system.&lt;/p&gt; &lt;p&gt;Tahoe-LAFS is a system that helps you to store files. You run a client program on your computer, which talks to one or more storage servers on other computers. When you tell your client to store a file, it will encrypt that file, encode it into multiple pieces, then spread those pieces out among multiple servers. The pieces are all encrypted and protected against modifications. Later, when you ask your client to retrieve the file, it will find the necessary pieces, make sure they haven’t been corrupted, reassemble them, and decrypt the result.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;linux-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/&#34;&gt;Linux Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#split-a-file-into-many-with-equal-number-of-lines&#34;&gt;Explain how to split a file into many with equal number of lines.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;split&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;200000&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;filename
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#identify-what-a-string-or-file-contains&#34;&gt;Explain how to identify what a string or file contains.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Using &lt;a href=&#34;https://github.com/bee-san/pyWhat&#34;&gt;pywhat&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#allocate-space-for-a-virtual-filesystem&#34;&gt;Explain how to allocate space for a virtual filesystem.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;fallocate&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;20G&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/path/to/file
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#bypass-client-ssl-certificate-with-cli-tool&#34;&gt;Document how to bypass client SSL certificate with a cli tool.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Websites that require clients to authorize with an TLS certificate are difficult to interact with through command line tools that don&#39;t support this feature.&lt;/p&gt; &lt;p&gt;To solve it, we can use a transparent proxy that does the exchange for us.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;afew&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_tabs/&#34;&gt;afew&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Explain how to use tabs, buffers and windows in vim.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce afew.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/afewmail/afew&#34;&gt;afew&lt;/a&gt; is an &lt;a href=&#34;http://notmuchmail.org/initial_tagging/&#34;&gt;initial tagging script&lt;/a&gt; for &lt;a href=&#34;https://lyz-code.github.io/blue-book/notmuch/&#34;&gt;notmuch mail&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Its basic task is to provide automatic tagging each time new mail is registered with &lt;code&gt;notmuch&lt;/code&gt;. In a classic setup, you might call it after &lt;code&gt;notmuch new&lt;/code&gt; in an offlineimap post sync hook.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;alot&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/vim/vim_plugins/&#34;&gt;alot&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/vim/vim_plugins/#issues&#34;&gt;Follow the issue to add elipsis instead of ... in vim-abolish.&lt;/a&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Forget to use abolish to insert the elipsis symbol.&lt;/p&gt; &lt;p&gt;Tpope said that it&#39;s not going to happen.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce vim-easymotion.&lt;/p&gt; &lt;p&gt;EasyMotion provides a much simpler way to use some motions in vim. It takes the &lt;code&gt;&amp;lt;number&amp;gt;&lt;/code&gt; out of &lt;code&gt;&amp;lt;number&amp;gt;w&lt;/code&gt; or &lt;code&gt;&amp;lt;number&amp;gt;f{char}&lt;/code&gt; by highlighting all possible choices and allowing you to press one key to jump directly to the target.&lt;/p&gt; &lt;p&gt;When one of the available motions is triggered, all visible text preceding or following the cursor is faded, and motion targets are highlighted.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Reorganization: Move vim-test to the plugins page.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Typo.&lt;/p&gt; &lt;p&gt;There was a missing comma in the list.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/vim/vim_plugins/#vim-easymotion&#34;&gt;Explain how to configure the vim-easymotion movement keys.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce alot.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/pazz/alot&#34;&gt;alot&lt;/a&gt; is a terminal-based mail user agent based on the &lt;a href=&#34;https://lyz-code.github.io/blue-book/notmuch/&#34;&gt;notmuch mail indexer&lt;/a&gt;. It is written in python using the urwid toolkit and features a modular and command prompt driven interface to provide a full MUA experience.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;activitywatch&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/activitywatch/&#34;&gt;ActivityWatch&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce ActivityWatch tracking software.&lt;/p&gt; &lt;p&gt;It&#39;s a web application that can be installed both in Linux and Android that automatically tracks where you spend the time on.&lt;/p&gt; &lt;p&gt;Super interesting for life logging and automating stuff. Until I save some time to react on the data, I&#39;ll just gather it and see how to aggregate it.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Add week insights.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/ActivityWatch/aw-watcher-web/issues/20&#34;&gt;The browser watcher is not very accurate&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;The vim editor watcher doesn&#39;t add &lt;a href=&#34;https://github.com/ActivityWatch/aw-watcher-vim/issues/19&#34;&gt;git branch information&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;Syncing data between devices &lt;a href=&#34;https://github.com/ActivityWatch/activitywatch/issues/35&#34;&gt;is not yet supported&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;beancount&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/beancount/&#34;&gt;beancount&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Introduce the cli double entry accounting program.&lt;/li&gt; &lt;li&gt;New: Add links on how to use as a library.&lt;/li&gt; &lt;li&gt;Correction: Correct the git repository link.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;beets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/beets/&#34;&gt;Beets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Beets the music management library.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://beets.io/&#34;&gt;Beets&lt;/a&gt; is a music management library used to get your music collection right once and for all. It catalogs your collection, automatically improving its metadata as it goes using the MusicBrainz database. Then it provides a set of tools for manipulating and accessing your music.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;dunst&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/dunst/&#34;&gt;dunst&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce dunst.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://dunst-project.org/&#34;&gt;Dunst&lt;/a&gt; is a lightweight replacement for the notification daemons provided by most desktop environments. It’s very customizable, isn’t dependent on any toolkits, and therefore fits into those window manager centric setups we all love to customize to perfection.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;dynamic-dns&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/dynamicdns/&#34;&gt;Dynamic DNS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the Dynamic DNS concept.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Dynamic_DNS&#34;&gt;Dynamic DNS (DDNS)&lt;/a&gt; is a method of automatically updating a name server in the Domain Name Server (DNS), often in real time, with the active DDNS configuration of its configured hostnames, addresses or other information.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;elasticsearch&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/elasticsearch/&#34;&gt;elasticsearch&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Explain how to reindex an index.&lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Explain how to restore only some indices.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-X&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;POST&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;{{ url }}/_snapshot/{{ backup_path }}/{{ snapshot_name }}/_restore?pretty&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-H&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Content-Type: application/json&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;  &#34;indices&#34;: &#34;{{ index_to_restore }}&#34;,&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;}&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/elasticsearch/#fix-circuit-breakers-triggers&#34;&gt;Explain how to fix Circuit breakers triggers.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Correct the way of closing an index.&lt;/p&gt; &lt;p&gt;Use a POST instead of a GET&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/elasticsearch/#knn-sizing&#34;&gt;Explain how to calculate the amount of memory required to do KNN operations.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/elasticsearch/#knn-warmup&#34;&gt;Explain how to do KNN warmup to speed up the queries.&lt;/a&gt;&lt;/li&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/elasticsearch/#deal-with-the-aws-timeout-service&#34;&gt;Explain how to deal with the AWS service timeout.&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;gajim&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gajim/&#34;&gt;Gajim&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce gajim.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://gajim.org/&#34;&gt;Gajim&lt;/a&gt; is the best Linux XMPP client in terms of end-to-end encryption support as it&#39;s able to speak OMEMO.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;github-cli&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gh/&#34;&gt;Github cli&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Basic usage of gh.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/cli/cli&#34;&gt;&lt;code&gt;gh&lt;/code&gt;&lt;/a&gt; is GitHub’s official command line tool.&lt;/p&gt; &lt;p&gt;It can be used to speed up common operations done with github, such as opening PRs, merging them or checking the checks of the PRs&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;graylog&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/graylog/&#34;&gt;Graylog&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Graylog.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.graylog.org/&#34;&gt;Graylog&lt;/a&gt; is a log management tool. The commit includes some tips like how to send a test message to check an input.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;haproxy&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/haproxy/&#34;&gt;HAProxy&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Add interesting guidelines on &lt;a href=&#34;https://github.com/jvehent/haproxy-aws&#34;&gt;how to configure HAProxy in AWS&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;hard-drive-health&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/hard_drive_health/&#34;&gt;Hard drive health&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Taking care of your hard drives.&lt;/p&gt; &lt;p&gt;Hard drives die, so we must be ready for that to happen. There are several solutions, such as using &lt;a href=&#34;https://en.wikipedia.org/wiki/RAID&#34;&gt;RAID&lt;/a&gt; to minimize the impact of a disk loss, but even then, we should monitor the &lt;a href=&#34;https://en.wikipedia.org/wiki/Bad_sector&#34;&gt;bad sectors&lt;/a&gt; to see when are our disks dying.&lt;/p&gt; &lt;p&gt;In the article we talk about &lt;a href=&#34;https://en.wikipedia.org/wiki/S.M.A.R.T.&#34;&gt;S.M.A.R.T&lt;/a&gt; and how to solve some hard drive problems.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;hushboard&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/husboard/&#34;&gt;Hushboard&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Husboard.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://kryogenix.org/code/hushboard/&#34;&gt;Hushboard&lt;/a&gt; is an utility that mutes your microphone while you’re typing.&lt;/p&gt; &lt;p&gt;(Thanks &lt;a href=&#34;https://m0wer.github.io/memento/computer_science/gnu_linux/hushboard/&#34;&gt;M0wer&lt;/a&gt;!)&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;jellyfin&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/&#34;&gt;Jellyfin&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the media system and monitor interesting issues.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://jellyfin.org/&#34;&gt;Jellyfin&lt;/a&gt; is a Free Software Media System that puts you in control of managing and streaming your media. It is an alternative to the proprietary Emby and Plex, to provide media from a dedicated server to end-user devices via multiple apps. Jellyfin is descended from Emby&#39;s 3.5.2 release and ported to the .NET Core framework to enable full cross-platform support. There are no strings attached, no premium licenses or features, and no hidden agendas: just a team who want to build something better and work together to achieve it.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Explain how to fix the stuck at login page issue.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;stop&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;jellyfin.service
mv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/jellyfin/data/jellyfin.db&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;,.bak&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;start&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;jellyfin.service
systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;stop&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;jellyfin.service
mv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/jellyfin/data/jellyfin.db&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;.bak,&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;start&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;jellyfin.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Explain how to fix the Intel Hardware transcoding.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-it&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;jellyfin&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/bin/bash
wget&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://repo.jellyfin.org/releases/server/ubuntu/versions/jellyfin-ffmpeg/4.3.2-1/jellyfin-ffmpeg_4.3.2-1-focal_amd64.deb
dpkg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;jellyfin-ffmpeg_4.3.2-1-focal_amd64.deb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: &lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/#wrong-image-covers&#34;&gt;Explain how to fix the wrong image covers.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Remove all the &lt;code&gt;jpg&lt;/code&gt; files of the directory and then fetch again the data from your favourite media management software.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/#issues&#34;&gt;Track the issue of trailers not working.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/#green-bars-in-the-reproduction&#34;&gt;Explain how to fix the green bars in the reproduction.&lt;/a&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/#stuck-at-login-page&#34;&gt;Fix the stuck at login page error.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you use &lt;a href=&#34;https://github.com/hrfee/jfa-go&#34;&gt;jfa-go&lt;/a&gt; for the invites, you may &lt;a href=&#34;https://github.com/hrfee/jfa-go/issues/101&#34;&gt;need to regenerate all the user profiles&lt;/a&gt;, so that the problem is not introduced again.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/#issues&#34;&gt;Track subtitles get delayed from the video on some devices issue.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;ffmpeg&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/ffmpeg/&#34;&gt;ffmpeg&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the program and multiple of it&#39;s uses.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.ffmpeg.org/&#34;&gt;ffmpeg&lt;/a&gt; is a complete, cross-platform solution to record, convert and stream audio and video.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;kitty&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/kitty/&#34;&gt;Kitty&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce kitty the terminal emulator.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://sw.kovidgoyal.net/&#34;&gt;kitty&lt;/a&gt; is a fast, feature-rich, GPU based terminal emulator written in C and Python with nice features for the keyboard driven humans like me.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/kitty/#scrollback-when-ssh-into-a-machine-doesn&#39;t-work&#34;&gt;Scrollback when ssh into a machine doesn&#39;t work.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This happens because the kitty terminfo files are not available on the server. You can ssh in using the following command which will automatically copy the terminfo files to the server:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kitty&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;+kitten&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ssh&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;myserver
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Enable infinite scrollback history.&lt;/p&gt; &lt;p&gt;To make the history scrollback infinite add the next lines:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;scrollback_lines -1
scrollback_pager_history_size 0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/kitty/#reasons-to-migrate-from-urxvt-to-kitty&#34;&gt;Reasons to migrate from urxvt to kitty.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;It doesn&#39;t fuck up your terminal colors.&lt;/li&gt; &lt;li&gt;You can use &lt;a href=&#34;https://lyz-code.github.io/blue-book/peek/&#34;&gt;peek&lt;/a&gt; to record your screen.&lt;/li&gt; &lt;li&gt;Easier to extend.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;luks&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/luks/luks/&#34;&gt;LUKS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/luks/luks/#change-a-key&#34;&gt;Explain how to change a LUKS key.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cryptsetup&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;luksChangeKey&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;luks_device&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;mkdocs&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/mkdocs/&#34;&gt;mkdocs&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Explain how to develop your own plugins.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Document the Navigation object and the on_nav event.&lt;/p&gt; &lt;p&gt;Useful if you develop MkDocs plugins, it holds the information to build the navigation of the site.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Describe navigation objects used in plugins.&lt;/p&gt; &lt;p&gt;Explain how to use the &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/mkdocs/#page&#34;&gt;Page&lt;/a&gt;, &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/mkdocs/#section&#34;&gt;Section&lt;/a&gt;, and &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/mkdocs/#sectionpage&#34;&gt;SectionPage&lt;/a&gt; objects.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: You need to edit the nav in the on_nav and not in the on_files event.&lt;/p&gt; &lt;p&gt;Even though it seems more easy to create the nav structure in the &lt;a href=&#34;#on_files&#34;&gt;&lt;code&gt;on_files&lt;/code&gt;&lt;/a&gt; event, by editing the &lt;code&gt;nav&lt;/code&gt; dictionary of the &lt;code&gt;config&lt;/code&gt; object, there is no way of returning the &lt;code&gt;config&lt;/code&gt; object in that event, so we&#39;re forced to do it in this event.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/mkdocs/#adding-new-files&#34;&gt;Explain how to add files through a plugin.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Long story short, use the &lt;code&gt;on_config&lt;/code&gt; event instead of &lt;code&gt;on_files&lt;/code&gt; and &lt;code&gt;on_nav&lt;/code&gt; if you need to add files and want to change the navigation menu.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Explain how to use MermaidJS diagrams.&lt;/p&gt; &lt;/li&gt; &lt;li&gt;New: Explain how to test mkdocs plugins.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/mkdocs/#material-theme-customizations&#34;&gt;Explain additions of version 7.1.0 of the material theme.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/mkdocs/#color-palette-toggle&#34;&gt;Dark-light mode switch&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/mkdocs/#back-to-top-button&#34;&gt;Back to top button&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;mopidy&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/mopidy/&#34;&gt;Mopidy&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the music server.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/mopidy/mopidy&#34;&gt;Mopidy&lt;/a&gt; is an extensible music server written in Python, that plays perfectly with &lt;a href=&#34;https://lyz-code.github.io/blue-book/beets/&#34;&gt;beets&lt;/a&gt; and the MPD ecosystem.&lt;/p&gt; &lt;p&gt;The awesome documentation, being Python based, the extension system, JSON-RPC, and JavaScript APIs make Mopidy a perfect base for your projects.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;oracle-database&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/oracle_database/&#34;&gt;Oracle Database&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Explain how to build an oracle database docker while feeling dirty inside.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;peek&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/peek/&#34;&gt;Peek&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Peek the screen recorder.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/phw/peek&#34;&gt;Peek&lt;/a&gt; is a simple animated GIF screen recorder with an easy to use interface.&lt;/p&gt; &lt;p&gt;If you try to use it with i3, you&#39;re going to have a bad time, you&#39;d &lt;a href=&#34;https://github.com/phw/peek#on-i3-the-recording-area-is-all-black-how-can-i-record-anything&#34;&gt;need to install&lt;/a&gt; &lt;a href=&#34;https://github.com/chjj/compton&#34;&gt;Compton&lt;/a&gt;, and then the elements &lt;a href=&#34;https://github.com/phw/peek#why-cant-i-interact-with-the-ui-elements-inside-the-recording-area&#34;&gt;may not even be clickable&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Add note that it works with kitty.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;syncthing&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/syncthing/&#34;&gt;Syncthing&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Improvement: Mention privacy configurations.&lt;/p&gt; &lt;p&gt;Disable the &lt;a href=&#34;https://docs.syncthing.net/users/security.html#global-discovery&#34;&gt;Global Discovery&lt;/a&gt; and &lt;a href=&#34;https://docs.syncthing.net/users/security.html#relay-connections&#34;&gt;Relaying connections&lt;/a&gt; options.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/syncthing/#syncthing-over-tor&#34;&gt;Investigate if Syncthing can be used over Tor.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I haven&#39;t found a reliable and safe way to do it, but I&#39;ve set a path to follow if you&#39;re interested.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;vim&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/&#34;&gt;Vim&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Configure Vim to set the upstream by default when git pushing.&lt;/li&gt; &lt;li&gt;New: Add vim landing page.&lt;/li&gt; &lt;li&gt;Reorganization: Refactor the vim_automation article into vim and vim_plugins.&lt;/li&gt; &lt;li&gt;Correction: Correct vim snippet to remember the folds when saving a file.&lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;android&#34;&gt;Android&lt;/h3&gt; &lt;h4 id=&#34;cone&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/cone/&#34;&gt;cone&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Introduce the mobile double entry accounting application.&lt;/li&gt; &lt;li&gt;Correction: Correct the description of the transaction to be beancount compatible.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;gadgetbridge&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gadgetbridge/&#34;&gt;GadgetBridge&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Add more guidelines to reverse engineer the band protocol.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;osmand&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/osmand/&#34;&gt;OsmAnd&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce OsmAnd.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://osmand.net&#34;&gt;OsmAnd&lt;/a&gt; is a mobile application for global map viewing and navigating based on &lt;a href=&#34;https://osm.org&#34;&gt;OpenStreetMaps&lt;/a&gt;. Perfect if you&#39;re looking for a privacy focused, community maintained open source alternative to google maps.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;signal&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/signal/&#34;&gt;Signal&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Introduce the messaging app and how to decrypt the backups.&lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;arts&#34;&gt;Arts&lt;/h2&gt; &lt;h3 id=&#34;writing&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/writing/writing/&#34;&gt;Writing&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Try vim-pencil without success, but love mdnav.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/chmp/mdnav&#34;&gt;mdnav&lt;/a&gt; opens links to urls or files when pressing &lt;code&gt;enter&lt;/code&gt; in normal mode over a markdown link, similar to &lt;code&gt;gx&lt;/code&gt; but more powerful. I specially like the ability of following &lt;code&gt;[self referencing link][]&lt;/code&gt; links, that allows storing the links at the bottom.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/writing/writing/#im-good-or-im-well&#34;&gt;Explain when to use I&#39;m good or I&#39;m well.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use I&#39;m well when referring to being ill, use I&#39;m good for the rest.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;grammar-and-orthography&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/writing/build_your_own_wiki/&#34;&gt;Grammar and Orthography&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Explain how to enable clickable navigation sections in your mkdocs repository.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/oprypin&#34;&gt;oprypin&lt;/a&gt; has solved it with the &lt;a href=&#34;https://github.com/oprypin/mkdocs-section-index&#34;&gt;mkdocs-section-index&lt;/a&gt; plugin.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Expand the introduction and add Dave&#39;s suggested link.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/writing/orthography/#where-to-add-your-pronouns&#34;&gt;Explain where to add your pronouns.&lt;/a&gt;&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Hi, I’m Lyz (he/him), I&#39;m writing to tell you…&lt;/p&gt; &lt;/blockquote&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/writing/orthography/#when-to-capitalize-after-a-question-mark&#34;&gt;Explain when to capitalize after a question mark.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If the sentence ends after the question mark you should capitalize, if it doesn&#39;t end, you shouldn&#39;t have used the question mark, since it ends a sentence.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add textstat tests.&lt;/p&gt; &lt;p&gt;To analyze the text readability&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/writing/orthography/#how-to-use-the-singular-they&#34;&gt;Explain how to use the singular &lt;code&gt;they&lt;/code&gt;.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Explain when to write won&#39;t or wont.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Won&#39;t is the correct way to contract will not.&lt;/li&gt; &lt;li&gt;Wont is a synonym of &#34;a habit&#34;. For example, &#34;He went for a morning jog, as was his wont&#34;.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/writing/orthography/#use-collocations&#34;&gt;Explain what collocations are and how to avoid the word very.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Collocation refers to a natural combination of words that are closely affiliated with each other. They make it easier to avoid overused or ambiguous words like &#34;very&#34;, &#34;nice&#34;, or &#34;beautiful&#34;, by using a pair of words that fit the context better and that have a more precise meaning.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/writing/orthography/#stop-saying-i-know&#34;&gt;Explain what can you use instead of I know.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Using &#34;I know&#34; may not be the best way to show the other person that you&#39;ve got the information. You can take the chance to use other words that additionally gives more context on how you stand with the information you&#39;ve received, thus improving the communication and creating a bond.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/writing/orthography/#use-of-z-or-s-in-some-words&#34;&gt;Explain the use of z or s in some words.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It looks like American english uses &lt;code&gt;z&lt;/code&gt; while British uses &lt;code&gt;s&lt;/code&gt;, some examples:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://writingexplained.org/organisation-vs-organization-difference&#34;&gt;Organizations vs organisation&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://english.stackexchange.com/questions/282621/authorization-vs-authorisation-im-in-some-real-dilemma&#34;&gt;Authorization vs authorisation&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://grammarist.com/spelling/customise-customize/&#34;&gt;Customized vs customised&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Both forms are correct, so choose the one that suits your liking.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;forking-this-garden&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/writing_style/&#34;&gt;Forking this garden&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/writing_style/#writing-style-books&#34;&gt;Analyze interesting books on writing style.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The elements of style by William Strunk Jr and E.B White&lt;/li&gt; &lt;li&gt;On writing well by William Zinsser&lt;/li&gt; &lt;li&gt;Bird by bird by Anne Lamott&lt;/li&gt; &lt;li&gt;On writing by Stephen King&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/writing_style/#how-to-end-a-letter&#34;&gt;Explain how to end a letter.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use Sincerely in doubt and Best if you have more confidence. Add a comma after the sign-off and &lt;em&gt;never&lt;/em&gt; use Cheers (it&#39;s what I&#39;ve been doing all my life &lt;code&gt;(◞‸◟；)&lt;/code&gt; ).&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Explain how to fork the blue book.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;digital-gardens&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/digital_garden/&#34;&gt;Digital Gardens&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the digital garden concept.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://joelhooks.com/digital-garden&#34;&gt;Digital Garden&lt;/a&gt; is a method of storing and maintaining knowledge in an maintainable, scalable and searchable way. They are also known as second brains.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;cooking&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/cooking/&#34;&gt;Cooking&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;New: Introduce the cooking art.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;cooking-basics&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/cooking_basics/&#34;&gt;Cooking Basics&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/cooking_basics/#boiling-an-egg&#34;&gt;Refactor the perfect technique to boil an egg.&lt;/a&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/cooking_basics/#boil-chickpeas-when-you&#39;ve-forgotten-to-soak-them&#34;&gt;Explain how to boil chickpeas when you&#39;ve forgotten to soak them.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Add a level teaspoon of baking soda to the pot and cook them as usual&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;pilates&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/pilates/&#34;&gt;Pilates&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the art.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Pilates&#34;&gt;Pilates&lt;/a&gt; is a physical fitness system based on controlled movements putting emphasis on alignment, breathing, developing a strong core, and improving coordination and balance. The core (or powerhouse), consisting of the muscles of the abdomen, low back, and hips, is thought to be the key to a person&#39;s stability.&lt;/p&gt; &lt;p&gt;Pilates&#39; system allows for different exercises to be modified in range of difficulty from beginner to advanced or to any other level, and also in terms of the instructor and practitioner&#39;s specific goals and/or limitations. Intensity can be increased over time as the body adapts itself to the exercises.&lt;/p&gt; &lt;p&gt;You can think of yoga, but without the spiritual aspects.&lt;/p&gt; &lt;p&gt;Also added:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;It&#39;s principles&lt;/li&gt; &lt;li&gt;The &lt;a href=&#34;https://lyz-code.github.io/blue-book/pilates/#swing-from-table&#34;&gt;swing from table&lt;/a&gt; exercise.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;board-gaming&#34;&gt;Board Gaming&lt;/h3&gt; &lt;h4 id=&#34;regicide&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/regicide/&#34;&gt;Regicide&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the awesome Regicide card game.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.badgersfrommars.com/&#34;&gt;Regicide&lt;/a&gt; is a wonderful cooperative card game for 1 to 4 players. It&#39;s awesome how they&#39;ve built such a rich game dynamic with a normal deck of cards. Even if you can play it with any deck, I suggest to buy &lt;a href=&#34;https://www.badgersfrommars.com/buy-regicide&#34;&gt;the deck they sell&lt;/a&gt; because their cards are magnificent and they deserve the money for their impressive game. Another thing I love about them is that even if you can&#39;t or don&#39;t want to pay for the game, they give the &lt;a href=&#34;https://www.badgersfrommars.com/assets/RegicideRulesA4.pdf?v=2&#34;&gt;rules for free&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;If you don&#39;t like reading the rules directly from their pdf (although it&#39;s quite short), they explain them in &lt;a href=&#34;https://www.badgersfrommars.com/regicide&#34;&gt;this video&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;I&#39;ve loved the game so much, that I&#39;ve created some variations of the rules to make each game more different and changeling.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;drawing&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/drawing/drawing/&#34;&gt;Drawing&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/drawing/drawing/#ellipses&#34;&gt;How to draw Ellipses.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Ellipses are the next basic shape we&#39;re going to study (after the lines). They are extremely important and notoriously annoying to draw. Important because we&#39;re going to be using ellipses in 2D space to represent circles that exist in 3D space.&lt;/p&gt; &lt;p&gt;In this section we:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Introduce the basic concepts surrounding the ellipses&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/drawing/drawing/#drawing-ellipses&#34;&gt;How to draw them&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;exercise-pool&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/drawing/exercise_pool/&#34;&gt;Exercise Pool&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/drawing/exercise_pool/#ellipses&#34;&gt;Add the Tables of ellipses drawing exercise.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This exercise is meant to get you used to drawing ellipses, in a variety of sizes, orientations and degrees. It also sets out a clear space each ellipse is meant to occupy, giving us a means to assess whether or not an ellipse was successful, or if there were visible mistakes (where it went outside of its allotted space, or ended up falling short). Practicing against set criteria, with a way to judge success/failure is an important element of learning. There&#39;s nothing wrong with failure - it&#39;s an opportunity to learn. Having a clearly defined task allows us to analyze those failures and make the most of them.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;origami&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/origami/&#34;&gt;Origami&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;New: Add mark1626 digital garden article on origamis.&lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;contact&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/contact/&#34;&gt;Contact&lt;/a&gt;&lt;/h2&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Update the XMPP address.&lt;/p&gt; &lt;p&gt;Riseup has stopped giving support for XMPP :(&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;other&#34;&gt;Other&lt;/h2&gt; &lt;ul&gt; &lt;li&gt;New: Add remote work tips.&lt;/li&gt; &lt;li&gt;New: Introduce lazy loading implementation paradigm with python.&lt;/li&gt; &lt;li&gt;New: Explain how to lazy load pydantic objects.&lt;/li&gt; &lt;li&gt;New: Explain my accounting automation workflow.&lt;/li&gt; &lt;li&gt;New: Feature mkdocs-rss-plugin as a solution of publishing mkdocs updates as an RSS.&lt;/li&gt; &lt;li&gt;New: Add a git issue tracker and markdown formatter.&lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Deprecate mkdocs issues.&lt;/p&gt; &lt;p&gt;They&#39;ve been fixed in the last release&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Suggest organize to act on computer file changes.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://organize.readthedocs.io/en/latest/&#34;&gt;organize&lt;/a&gt; looks good for automating processes on files. Maybe it&#39;s interesting to run it with &lt;a href=&#34;https://askubuntu.com/a/819290&#34;&gt;inotifywait&lt;/a&gt; instead of with a &lt;a href=&#34;https://github.com/tfeldmann/organize/issues/18&#34;&gt;cron job&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce Outrun.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/Overv/outrun&#34;&gt;Outrun&lt;/a&gt; lets you execute a local command using the processing power of another Linux machine.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Broken links.&lt;/p&gt; &lt;p&gt;Removed the link to (everything_i_know.md) since it no longer exists. Updated some links that where broken due to a folder structure change.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Explain how to select a random choice from &lt;code&gt;Enum&lt;/code&gt; objects.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pydantic/&#34;&gt;pydantic&lt;/a&gt; uses &lt;code&gt;Enum&lt;/code&gt; objects to define &lt;a href=&#34;https://pydantic-docs.helpmanual.io/usage/types/#enums-and-choices&#34;&gt;the choices of fields&lt;/a&gt;, so we need them to create the factories of those objects.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Improve the periodic tasks and application metrics monitoring.&lt;/p&gt; &lt;p&gt;Setup an &lt;a href=&#34;https://healthchecks.io/&#34;&gt;healthchecks&lt;/a&gt; instance with the &lt;a href=&#34;https://docs.linuxserver.io/images/docker-healthchecks&#34;&gt;linuxserver image&lt;/a&gt; to monitor cronjobs.&lt;/p&gt; &lt;p&gt;For the notifications either use the &lt;a href=&#34;https://healthchecks.io/docs/configuring_prometheus/&#34;&gt;prometheus metrics&lt;/a&gt; or an &lt;a href=&#34;https://github.com/healthchecks/healthchecks/issues/271&#34;&gt;apprise&lt;/a&gt; compatible system.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Explain how to check if an rsync command has gone well.&lt;/p&gt; &lt;p&gt;Run &lt;code&gt;diff -r --brief source/ dest/&lt;/code&gt;, and check that there is no output.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Reorganization: Reorder the sections of the site navigation menu.&lt;/p&gt; &lt;p&gt;Give more importance to Coding, Activism and Life Management, reducing the Software Architecture and Data Analysis sections.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce the tool management section.&lt;/p&gt; &lt;p&gt;Most of the tasks or processes we do involve some kind of tool, the better you know how to use them, the better your efficiency will be. The more you use a tool, the more it&#39;s worth the investment of time to improve your usage of it.&lt;/p&gt; &lt;p&gt;Whenever I use a tool, I try to think if I could configure it or use it in a way that will make it easier or quicker. Don&#39;t go crazy and try to change everything. Go step by step, and once you&#39;ve internalized the improvement, implement the next.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Reorganization: Move the tasks tools from the task management article to their own.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;aside class=&#34;md-source-file&#34;&gt; &lt;span class=&#34;md-source-file__fact&#34;&gt; &lt;span class=&#34;md-icon&#34; title=&#34;Last update&#34;&gt; &lt;svg viewbox=&#34;0 0 24 24&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z&#34;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt; &lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago&#34; title=&#34;November 27, 2024 15:36:58 UTC&#34;&gt;&lt;span class=&#34;timeago&#34; datetime=&#34;2024-11-27T15:36:58+00:00&#34; locale=&#34;en&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date&#34; title=&#34;November 27, 2024 15:36:58 UTC&#34;&gt;2024-11-27&lt;/span&gt; &lt;/span&gt; &lt;/aside&gt; &lt;/article&gt;</description>
      <link>https://lyz-code.github.io/blue-book/newsletter/2021/</link>
      <pubDate>2024-11-27 15:36:58+00:00</pubDate>
      <source url="https://lyz-code.github.io/blue-book/yearly.xml">The Blue Book</source>
      <guid isPermaLink="true">https://lyz-code.github.io/blue-book/newsletter/2021/</guid>
      
    </item>
    
    <item><title>2020</title>
      <author>Lyz</author>
      <description>&lt;article class=&#34;md-content__inner md-typeset&#34;&gt;  &lt;h2 id=&#34;meta&#34;&gt;Meta&lt;/h2&gt; &lt;h3 id=&#34;projects&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/projects/&#34;&gt;Projects&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;New: Update information on active projects.&lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;devops&#34;&gt;DevOps&lt;/h2&gt; &lt;h3 id=&#34;infrastructure-as-code&#34;&gt;Infrastructure as Code&lt;/h3&gt; &lt;h4 id=&#34;helm&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/helm/helm/&#34;&gt;Helm&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Introduce helm-git to install charts directly from git repositories.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;helmfile&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/helmfile/&#34;&gt;Helmfile&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Tell how to make long diffs usable.&lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;infrastructure-solutions&#34;&gt;Infrastructure Solutions&lt;/h3&gt; &lt;h4 id=&#34;kubernetes&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes/&#34;&gt;Kubernetes&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Explain jobs, cronjobs and how to monitor them with prometheus.&lt;/li&gt; &lt;li&gt;New: Explain how to debug cronjob logs.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;kubectl&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubectl/kubectl/&#34;&gt;Kubectl&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Add kubectl command cheatsheet.&lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;continuous-integration&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/ci/&#34;&gt;Continuous Integration&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;Reorganization: Split CI documents into their own pages.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;black&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/mypy/&#34;&gt;Black&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Explain how to reveal the type of an expression.&lt;/li&gt; &lt;li&gt;Improvement: Add git link.&lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Configure black to process long lines.&lt;/p&gt; &lt;p&gt;Use the &lt;code&gt;--experimental-string-procesing&lt;/code&gt; flag to process long lines.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce the alex linter.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/alex/&#34;&gt;Alex&lt;/a&gt; helps you find gender favoring, polarizing, race related, religion inconsiderate, or other unequal phrasing in text.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Explain how to skip one line.&lt;/p&gt; &lt;/li&gt; &lt;li&gt;New: Explain how to fix the Module X has no attribute Y.&lt;/li&gt; &lt;li&gt;New: Explain how to prevent the formatter on some lines.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;yamlfix&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/flakeheaven/&#34;&gt;Yamlfix&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce flakeheaven python linter.&lt;/p&gt; &lt;p&gt;Flakehell is a &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/flake8/&#34;&gt;Flake8&lt;/a&gt; wrapper to make it cool.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Annotate the slowness of the bandit tests in pre-commit.&lt;/p&gt; &lt;/li&gt; &lt;li&gt;New: Add yamlfix formatter.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;markdownlint&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/markdownlint/&#34;&gt;Markdownlint&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the markdownlint linter.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/markdownlint/&#34;&gt;markdownlint&lt;/a&gt; is A linter for Markdown files.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;proselint&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/proselint/&#34;&gt;Proselint&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce proselint linter.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/amperser/proselint/&#34;&gt;Proselint&lt;/a&gt; is another linter for prose.&lt;/p&gt; &lt;p&gt;feat(write-good) introduce the write-good linter&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/btford/write-good&#34;&gt;write-good&lt;/a&gt; is a naive linter for English prose.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;automating-processes&#34;&gt;Automating Processes&lt;/h3&gt; &lt;h4 id=&#34;cookiecutter&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/cookiecutter/&#34;&gt;cookiecutter&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Add cookiecutter template testing guidelines.&lt;/li&gt; &lt;li&gt;New: Explain how to remove unwanted directories.&lt;/li&gt; &lt;li&gt;New: Explain how to use a default configuration for all your templates.&lt;/li&gt; &lt;li&gt;Improvement: Add references on why is not easy to update cookiecutter templates.&lt;/li&gt; &lt;li&gt;New: Explain how to debug failing cookiecutter tests.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;cruft&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/cruft/&#34;&gt;cruft&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce cruft tool to manage cookiecutter templates.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://cruft.github.io/cruft/&#34;&gt;cruft&lt;/a&gt; allows you to maintain all the necessary boilerplate for packaging and building projects separate from the code you intentionally write. Fully compatible with existing &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/cookiecutter/&#34;&gt;Cookiecutter&lt;/a&gt; templates.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;monitoring&#34;&gt;Monitoring&lt;/h3&gt; &lt;h4 id=&#34;prometheus&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/prometheus/&#34;&gt;Prometheus&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Explain how to find a metric name.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add statistical analysis on instance sizes using prometheus metrics.&lt;/p&gt; &lt;p&gt;Explain how to configure prometheus to automatically check if your instances are of the correct size and which are your bottlenecks.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Explain how to install with docker.&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Reorganization: Move the installation of docker to prometheus install.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;node-exporter&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/node_exporter/&#34;&gt;Node Exporter&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Filter out stopped instances.&lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;coding&#34;&gt;Coding&lt;/h2&gt; &lt;h3 id=&#34;python&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/python/&#34;&gt;Python&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;New: Add cookiecutter documentation.&lt;/li&gt; &lt;li&gt;New: Add docker construction for a python project.&lt;/li&gt; &lt;li&gt;New: Add commit guidelines with commitizen.&lt;/li&gt; &lt;li&gt;Correction: Type hints of subclasses of abstract classes.&lt;/li&gt; &lt;li&gt;New: Introduce the python docstrings.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add python snippets article.&lt;/p&gt; &lt;p&gt;Includes the generation of OpenSSH keys with the cryptography library&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Improvement: Correct typo in the generation of ssh keys.&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Correction: Add email to the generated ssh snippet.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Explain how to make multiline code look clean.&lt;/p&gt; &lt;p&gt;Use &lt;code&gt;textwrap.dedent()&lt;/code&gt; to define variables that require multiline strings&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Explain how to play a file inside python.&lt;/p&gt; &lt;/li&gt; &lt;li&gt;New: Explain how to save a python object to a string using ruamel parser.&lt;/li&gt; &lt;li&gt;New: Explain how to do a deep copy of a dictionary.&lt;/li&gt; &lt;li&gt;New: Explain how to solve the R0201 pylint error.&lt;/li&gt; &lt;li&gt;New: Do an initial analysis on Python profiling.&lt;/li&gt; &lt;li&gt;New: Introduce some ideas on optimization of python code.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;alembic&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/alembic/&#34;&gt;Alembic&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;Correction: Explain how to use alembic from a python scripts and not.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;click&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/click/&#34;&gt;Click&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Explain how to setup and test a click application.&lt;/li&gt; &lt;li&gt;New: Introduce click arguments.&lt;/li&gt; &lt;li&gt;New: Explain how to accept options from environmental variables and how to handle contexts.&lt;/li&gt; &lt;li&gt;Correction: Add note on capturing stderr and stdout with caplog instead of click methods.&lt;/li&gt; &lt;li&gt;New: Introduce the boolean options and variadic arguments.&lt;/li&gt; &lt;li&gt;New: Explain how to use a default command to a click group.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Improve arguments documentation.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Add example on how to use variadic arguments.&lt;/li&gt; &lt;li&gt;Explain how to use File and Path click arguments&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Explain how to set the allowable values for an argument.&lt;/p&gt; &lt;/li&gt; &lt;li&gt;New: Explain how to hide a command from the --help output.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;dash&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/dash/&#34;&gt;Dash&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce dash and dash-leaflet.&lt;/p&gt; &lt;p&gt;Explain how to initiate dash and how to create a map with dash-leaflet&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Explain how to interact with programs that ask for user input.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;type-hints&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/type_hints/&#34;&gt;Type Hints&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Improve the definition of objects with multiple types with TypeVar.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Explain how to use the TypedDict instead of Dict.&lt;/p&gt; &lt;p&gt;Useful if the different keys have different types&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;code-styling&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/deepdiff/&#34;&gt;Code Styling&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Introduce the deepdiff library.&lt;/li&gt; &lt;li&gt;New: Explain how to fix the Pylint R0201 error.&lt;/li&gt; &lt;li&gt;New: Explain why we can safely ignore W1203.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;factoryboy&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/factoryboy/&#34;&gt;FactoryBoy&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;Correction: Add warning that generating your own attributes doesn&#39;t work anymore.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;faker&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/faker/&#34;&gt;Faker&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Explain how to populate the faker fixture with random seeds.&lt;/li&gt; &lt;li&gt;Correction: Improve the way of generating random seed.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;folium&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/folium/&#34;&gt;Folium&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Explain how to use folium, change tileset and load data.&lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Change the order of the layers.&lt;/p&gt; &lt;p&gt;Openstreetmaps is more clear than the IGN, so the waypoints are better seen&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pytest&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pytest/&#34;&gt;Pytest&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Explain what fixtures are.&lt;/li&gt; &lt;li&gt;New: Tell how to use a fixture more than once in a function.&lt;/li&gt; &lt;li&gt;New: Document the capsys, caplog and tmpdir builtin fixtures.&lt;/li&gt; &lt;li&gt;New: Add freezegun fixture.&lt;/li&gt; &lt;li&gt;New: Explain how to save the fixtures into a separate file.&lt;/li&gt; &lt;li&gt;New: Explain the different parametrization options. Introduce the awesome pytest-cases.&lt;/li&gt; &lt;li&gt;New: Explain how to use marks to group the tests.&lt;/li&gt; &lt;li&gt;New: Explain how to test error raising with pytest.&lt;/li&gt; &lt;li&gt;Improvement: Solve W0621 Redefining name %r from outer scope (line %s) error.&lt;/li&gt; &lt;li&gt;New: Explain how to change the log level with the caplog.&lt;/li&gt; &lt;li&gt;Correction: Add link to the unpack_fixture section.&lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Explain how to better use with pytest.raises snippets.&lt;/p&gt; &lt;p&gt;To capture the message in a cleaner way&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;mkdocstrings&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/mkdocstrings/&#34;&gt;mkdocstrings&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the mkdocstrings library.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://pawamoy.github.io/mkdocstrings&#34;&gt;mkdocstrings&lt;/a&gt; is a library to automatically generate &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/mkdocs/&#34;&gt;mkdocs&lt;/a&gt; pages from the code docstrings.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;passpy&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/passpy/&#34;&gt;Passpy&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the passpy library.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/bfrascher/passpy&#34;&gt;passpy&lt;/a&gt; a platform independent library and cli that is compatible with &lt;a href=&#34;http://www.passwordstore.org/&#34;&gt;ZX2C4&#39;s pass&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pydantic&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pydantic/&#34;&gt;Pydantic&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Introduce pydantic with it&#39;s models and types.&lt;/li&gt; &lt;li&gt;New: Explain how validators work.&lt;/li&gt; &lt;li&gt;New: Explain how to export the models.&lt;/li&gt; &lt;li&gt;New: Explain how to validate functions and use the mypy plugin.&lt;/li&gt; &lt;li&gt;New: Explain how to initialize empty iterables on attributes.&lt;/li&gt; &lt;li&gt;New: Explain how to solve the E0611 error.&lt;/li&gt; &lt;li&gt;Correction: Explain how to solve the E0611 error in code lines.&lt;/li&gt; &lt;li&gt;Correction: Correct pylint R0201 on pydantic models.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pypika&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pypika/&#34;&gt;Pypika&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Introduce pypika.&lt;/li&gt; &lt;li&gt;New: Explain how to select, filter and delete data.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;sqlite3&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/sqlite3/&#34;&gt;sqlite3&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Introduce the sqlite python library.&lt;/li&gt; &lt;li&gt;New: Explain how to get the columns of a sqlite3 query.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;talkey&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/talkey/&#34;&gt;Talkey&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Introduce text to speech python library.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;yoyo&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/yoyo/&#34;&gt;Yoyo&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Introduce yoyo database migration tool.&lt;/li&gt; &lt;li&gt;New: Explain how to do yoyo table relationships.&lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;json&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/json/json/&#34;&gt;JSON&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;New: Add json linters and fixers.&lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;sql&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/sql/sql/&#34;&gt;SQL&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;New: Introduce the sql data types.&lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;sqlite&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/sqlite/&#34;&gt;SQLite&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;New: Introduce sqlite and it&#39;s upsert feature.&lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;software-architecture&#34;&gt;Software Architecture&lt;/h2&gt; &lt;h3 id=&#34;domain-driven-design&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/architecture/domain_driven_design/&#34;&gt;Domain Driven Design&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;New: Explain how to inject fake dependencies into e2e tests with click.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;repository-pattern&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/architecture/repository_pattern/&#34;&gt;Repository Pattern&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Warn about the definition of attributes created by the ORMs.&lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;life-management&#34;&gt;Life Management&lt;/h2&gt; &lt;h3 id=&#34;strategy&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/strategy/&#34;&gt;Strategy&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce strategy document.&lt;/p&gt; &lt;p&gt;Differentiate between strategic planning and strategic thinking&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;health&#34;&gt;Health&lt;/h2&gt; &lt;h3 id=&#34;sleep&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/sleep/&#34;&gt;Sleep&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;New: Explain the benefits of sleep, the consequences of lack of sleep and the physiological effects of sleep including the circadian rhythm and what is melatonin.&lt;/li&gt; &lt;li&gt;New: Explain sleep pressure, caffeine and the relationship with the circadian rhythm.&lt;/li&gt; &lt;li&gt;New: Explain the independence between circadian and sleep pressure.&lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;operative-systems&#34;&gt;Operative Systems&lt;/h2&gt; &lt;h3 id=&#34;linux&#34;&gt;Linux&lt;/h3&gt; &lt;h4 id=&#34;haproxy&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/haproxy/&#34;&gt;HAProxy&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Introduce haproxy and how to do a reverse proxy with it.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;mkdocs&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/mkdocs/&#34;&gt;mkdocs&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;Correction: Correct meditation navigation element.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;monica&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/monica/&#34;&gt;monica&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Add monica installation.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;vim&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim/&#34;&gt;Vim&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Add ale language server processor Vim plugin.&lt;/li&gt; &lt;li&gt;New: Add only part of files to the index to stage.&lt;/li&gt; &lt;li&gt;New: Create ALEToggleFixer command to enable/disable fixers.&lt;/li&gt; &lt;li&gt;New: Make fugitive commit workflow more user friendly.&lt;/li&gt; &lt;li&gt;Correction: Add movement mappings for the commit message window.&lt;/li&gt; &lt;li&gt;New: Explain how to use YouCompleteMe to complete prose.&lt;/li&gt; &lt;li&gt;Correction: Explain how to limit the autosuggestion results to one when writing prose.&lt;/li&gt; &lt;li&gt;New: Explain how to search synonyms inside vim.&lt;/li&gt; &lt;li&gt;Correction: Improve the environment to write commits with more bindings and restoring bindings once you close the message.&lt;/li&gt; &lt;li&gt;New: Explain how to manage python foldings.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;zfs&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/&#34;&gt;ZFS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Introduce zfs and some basic commands.&lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;arts&#34;&gt;Arts&lt;/h2&gt; &lt;h3 id=&#34;writing&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/writing/writing/&#34;&gt;Writing&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;New: Add there is/are avoidance pattern.&lt;/li&gt; &lt;li&gt;New: Explain the guidelines and tools I use for writing.&lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;meditation&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/meditation/&#34;&gt;Meditation&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;New: Define meditation and it&#39;s types.&lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;video-gaming&#34;&gt;Video Gaming&lt;/h3&gt; &lt;h4 id=&#34;the-battle-for-wesnoth&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/wesnoth/&#34;&gt;The Battle for Wesnoth&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Explain how to play the loyalist civilization.&lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;other&#34;&gt;Other&lt;/h2&gt; &lt;ul&gt; &lt;li&gt;New: Add sh awesome library.&lt;/li&gt; &lt;li&gt;Correction: Fix broken links.&lt;/li&gt; &lt;li&gt;New: Add factoryboy factory usage.&lt;/li&gt; &lt;li&gt;New: Add the xy problem.&lt;/li&gt; &lt;li&gt;New: Add tinydb documentation.&lt;/li&gt; &lt;li&gt;New: Add prevent cookiecutter from processing some files docs.&lt;/li&gt; &lt;li&gt;New: Add first cutting shapes steps.&lt;/li&gt; &lt;li&gt;Correction: Improve the changelog generation with commitizen.&lt;/li&gt; &lt;li&gt;Correction: Remove unwanted gifs on rave dances.&lt;/li&gt; &lt;li&gt;New: Add kicking-running man and tap spin.&lt;/li&gt; &lt;li&gt;New: Prevent additional whitespaces when jinja condition is not met.&lt;/li&gt; &lt;li&gt;Correction: Correct the running man.&lt;/li&gt; &lt;li&gt;New: Add how to keep historical data on database table changes.&lt;/li&gt; &lt;li&gt;New: List all process swap space usage.&lt;/li&gt; &lt;li&gt;New: Introduce the click python library.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add more steps.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Quick tempo running man&lt;/li&gt; &lt;li&gt;Quick tempo T-Step&lt;/li&gt; &lt;li&gt;Francis T-Step&lt;/li&gt; &lt;li&gt;Sacco kicks&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add Francis spin and first version of dance routine.&lt;/p&gt; &lt;p&gt;Corrected how to reach the quick tempo running man.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: More guidelines on how to speed up the running man.&lt;/p&gt; &lt;p&gt;And refactor in different files&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add times for next steps to learn.&lt;/p&gt; &lt;/li&gt; &lt;li&gt;New: Added ash, birch and beech description.&lt;/li&gt; &lt;li&gt;New: Introduce wireguard.&lt;/li&gt; &lt;li&gt;New: Explain how to debug elasticsearch yellow state.&lt;/li&gt; &lt;li&gt;Correction: Update python ci docs.&lt;/li&gt; &lt;li&gt;New: Explain how to solve cyclic imports when using type hints.&lt;/li&gt; &lt;li&gt;New: Evaluate the different solutions to programmatically interact with databases.&lt;/li&gt; &lt;li&gt;Correction: Remove xkcd image.&lt;/li&gt; &lt;li&gt;Reorganization: Extract type hints to it&#39;s own file.&lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Bump material version to 6.0.2.&lt;/p&gt; &lt;p&gt;Also take the chance to move images directory to img&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Correct repository pattern images path.&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Correction: Correct image paths.&lt;/li&gt; &lt;li&gt;Correction: Add note on the flexibility of query builders.&lt;/li&gt; &lt;li&gt;Correction: Remove type hints from python code styling.&lt;/li&gt; &lt;li&gt;New: Explain the use of Generic typing.&lt;/li&gt; &lt;li&gt;Correction: Correct domain driven design image path.&lt;/li&gt; &lt;li&gt;Correction: Remove broken links.&lt;/li&gt; &lt;li&gt;New: Explain how to make your python packages mypy compliant.&lt;/li&gt; &lt;li&gt;Correction: Explain how to remove all pip packages from a virtualenv.&lt;/li&gt; &lt;li&gt;Correction: Discourage the use of pip-tools in the CI.&lt;/li&gt; &lt;li&gt;Correction: Explain how to get started.&lt;/li&gt; &lt;li&gt;Correction: References between articles.&lt;/li&gt; &lt;li&gt;New: Explain how to fix W0707 mypy error.&lt;/li&gt; &lt;li&gt;New: Introduce wesnoth, and the northerners and rebels civilizations.&lt;/li&gt; &lt;li&gt;New: Explain how to use Wake on Lan.&lt;/li&gt; &lt;li&gt;New: Explain how to use TypeVar to specify children class.&lt;/li&gt; &lt;li&gt;New: Explain how to solve W0106 in list comprehensions.&lt;/li&gt; &lt;li&gt;New: Explain how to solve SIM105.&lt;/li&gt; &lt;/ul&gt; &lt;aside class=&#34;md-source-file&#34;&gt; &lt;span class=&#34;md-source-file__fact&#34;&gt; &lt;span class=&#34;md-icon&#34; title=&#34;Last update&#34;&gt; &lt;svg viewbox=&#34;0 0 24 24&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z&#34;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt; &lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago&#34; title=&#34;November 27, 2024 15:36:58 UTC&#34;&gt;&lt;span class=&#34;timeago&#34; datetime=&#34;2024-11-27T15:36:58+00:00&#34; locale=&#34;en&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date&#34; title=&#34;November 27, 2024 15:36:58 UTC&#34;&gt;2024-11-27&lt;/span&gt; &lt;/span&gt; &lt;/aside&gt; &lt;/article&gt;</description>
      <link>https://lyz-code.github.io/blue-book/newsletter/2020/</link>
      <pubDate>2024-11-27 15:36:58+00:00</pubDate>
      <source url="https://lyz-code.github.io/blue-book/yearly.xml">The Blue Book</source>
      <guid isPermaLink="true">https://lyz-code.github.io/blue-book/newsletter/2020/</guid>
      
    </item>
    
  </channel>
</rss>