<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Random forest</title>
    <link>http://sarg.org.ru/index.xml</link>
    <description>Recent content on Random forest</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <managingEditor>sarg@sarg.org.ru (Sergey Trofimov)</managingEditor>
    <webMaster>sarg@sarg.org.ru (Sergey Trofimov)</webMaster>
    <lastBuildDate>Sat, 29 Aug 2026 21:12:54 +0200</lastBuildDate><atom:link href="http://sarg.org.ru/index.xml" rel="self" type="application/rss+xml" />

    <item>
      <title>TOTP is easy</title>
      <link>http://sarg.org.ru/blog/totp-is-easy/</link>
      <pubDate>Fri, 01 Aug 2025 00:00:00 +0200</pubDate>
      <author>sarg@sarg.org.ru (Sergey Trofimov)</author>
      <guid>http://sarg.org.ru/blog/totp-is-easy/</guid>
      <description>&lt;p&gt;One-time passwords are everywhere. Let&amp;rsquo;s learn how to generate one yourself. The
&lt;a href=&#34;https://www.rfc-editor.org/rfc/rfc4226&#34;&gt;algorithm&lt;/a&gt; is simple: calculate an HMAC over an 8-byte counter and truncate it
for display. Truncation involves using the last four bits of the hash to
determine an offset, from which four bytes are extracted. The most significant
bit of these four bytes is masked out (to avoid negative values), and the
remaining 31 bits are treated as a big-endian integer. Finally, the decimal
representation of this integer is truncated to the required length.&lt;/p&gt;
&lt;p&gt;The counter must be synchronised between the generator and validator. For HOTP
it is the sequential index of the password; for TOTP it is derived from current
time.&lt;/p&gt;
&lt;p&gt;The algorithm translates to this Python program:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;hmac&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;base64&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;hashlib&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;time&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#00a000&#34;&gt;hotp&lt;/span&gt;(secret: &lt;span style=&#34;color:#a2f&#34;&gt;bytes&lt;/span&gt;, counter: &lt;span style=&#34;color:#a2f&#34;&gt;int&lt;/span&gt;, length: &lt;span style=&#34;color:#a2f&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;6&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    h &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; hmac&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;new(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        base64&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;b32decode(secret),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        counter&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;to_bytes(&lt;span style=&#34;color:#666&#34;&gt;8&lt;/span&gt;, &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;big&amp;#34;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        hashlib&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;sha1,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    )&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;digest()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    o &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; h[&lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;1&lt;/span&gt;] &lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;0xF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    res &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a2f&#34;&gt;int&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;from_bytes(h[o : o &lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;4&lt;/span&gt;], &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;big&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;0x7FFFFFFF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a2f&#34;&gt;str&lt;/span&gt;(res &lt;span style=&#34;color:#666&#34;&gt;%&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;10&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;**&lt;/span&gt;length)&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;zfill(length)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#00a000&#34;&gt;totp&lt;/span&gt;(secret: &lt;span style=&#34;color:#a2f&#34;&gt;bytes&lt;/span&gt;, period: &lt;span style=&#34;color:#a2f&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;30&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;return&lt;/span&gt; hotp(secret, &lt;span style=&#34;color:#a2f&#34;&gt;int&lt;/span&gt;(time&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;time()) &lt;span style=&#34;color:#666&#34;&gt;//&lt;/span&gt; period)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;print&lt;/span&gt;(&lt;span style=&#34;color:#b44&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;HOTP: &lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;{&lt;/span&gt;hotp(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;SDACNQ37BVMBQ3Q5&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#666&#34;&gt;1&lt;/span&gt;)&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;print&lt;/span&gt;(&lt;span style=&#34;color:#b44&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;TOTP: &lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;{&lt;/span&gt;totp(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;SDACNQ37BVMBQ3Q5&amp;#39;&lt;/span&gt;)&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HOTP: 795526
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;TOTP: 467487
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    

    <item>
      <title>Literate Guix configuration</title>
      <link>http://sarg.org.ru/blog/literate-guix/</link>
      <pubDate>Sun, 22 Jun 2025 00:00:00 +0200</pubDate>
      <author>sarg@sarg.org.ru (Sergey Trofimov)</author>
      <guid>http://sarg.org.ru/blog/literate-guix/</guid>
      <description>&lt;h2 id=&#34;intro&#34;&gt;Intro&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;http://sarg.org.ru/ox-hugo/literate.txt&#34;&gt;This file&lt;/a&gt; is a literate configuration of a Guix and Emacs system. Tangling it
(&lt;code&gt;C-c C-v t&lt;/code&gt;) produces &lt;code&gt;home.scm&lt;/code&gt; , which could be then installed as usual.&lt;/p&gt;
&lt;p&gt;Using this template you&amp;rsquo;ll be able to structure a &lt;code&gt;home-environment&lt;/code&gt; definition in
a way that is convenient to you. Besides regular &lt;code&gt;noweb&lt;/code&gt; features, a new source
code block language is implemented, allowing templated configuration files (see
&lt;a href=&#34;#templated-files&#34;&gt;example&lt;/a&gt; below). Emacs configuration is included in the &lt;code&gt;home-environment&lt;/code&gt; as a
&lt;code&gt;package&lt;/code&gt; (see the &lt;a href=&#34;#config-package&#34;&gt;definition&lt;/a&gt;), which is built by tangling this org file.&lt;/p&gt;
&lt;p&gt;A couple settings to ease the use in emacs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;set tangle parameters&lt;/li&gt;
&lt;li&gt;eval and wrap &lt;code&gt;cfg&lt;/code&gt; blocks automatically&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;header&#34;&gt;Header&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;#+PROPERTY&lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;: header-args :noweb-prefix no :noweb yes :eval no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;#+PROPERTY&lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;: header-args:elisp :tangle config.el&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;#+PROPERTY&lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;: header-args:cfg :eval yes :cache yes :wrap &amp;#34;src text :noweb-ref guix-file&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;footer&#34;&gt;Footer&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Local Variables:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# eval: (add-hook &amp;#39;after-save-hook (lambda () (org-babel-tangle nil nil &amp;#34;scheme&amp;#34;)) 0 t)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# eval: (add-hook &amp;#39;org-babel-pre-tangle-hook #&amp;#39;org-babel-execute-buffer 0 t)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# End:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;template&#34;&gt;Template&lt;/h2&gt;
&lt;p&gt;Main template which tangles to &lt;code&gt;home.scm&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;#+begin_src scheme :tangle home.scm
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;use-modules&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;gnu&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;gnu&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;services&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;gnu&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;home&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;services&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;gnu&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;home&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;services&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;desktop&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;guix&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;gexp&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;guix&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;git-download&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;guix&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;build-system&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;copy&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;guix&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;packages&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;ice-9&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;receive&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;define &lt;/span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;pkg&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;x&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;color:#a2f&#34;&gt;string? &lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;x&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#00a000&#34;&gt;receive&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;package&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;out&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#00a000&#34;&gt;specification-&amp;gt;package+output&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;x&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if &lt;/span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;string=&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;out&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;out&lt;/span&gt;) &lt;span style=&#34;color:#b8860b&#34;&gt;package&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            (&lt;span style=&#34;color:#a2f&#34;&gt;list &lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;package&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;out&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#b8860b&#34;&gt;x&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;define &lt;/span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;chmod-computed-file&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;f&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;p&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#00a000&#34;&gt;computed-file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   (&lt;span style=&#34;color:#00a000&#34;&gt;computed-file-name&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;f&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#666&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;~&lt;/span&gt;(&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;begin &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$&lt;/span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;computed-file-gexp&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;f&lt;/span&gt;) (&lt;span style=&#34;color:#00a000&#34;&gt;chmod&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$output&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$p&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#666&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;:options&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;computed-file-options&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;f&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;home-environment&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;services&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#00a000&#34;&gt;cons*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   (&lt;span style=&#34;color:#00a000&#34;&gt;simple-service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#b8860b&#34;&gt;&amp;#39;files&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;home-files-service-type&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#666&#34;&gt;`&lt;/span&gt;((&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;.guile&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;%default-dotguile&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;.config/guix/channels.scm&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &lt;span style=&#34;color:#666&#34;&gt;,&lt;/span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;plain-file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;channels.scm&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#00a000&#34;&gt;simple-format&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;#f&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;~s&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;&amp;#39;&lt;/span&gt;(&lt;span style=&#34;color:#b8860b&#34;&gt;list&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;&amp;lt;&amp;lt;guix-channel&amp;gt;&amp;gt;&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#b8860b&#34;&gt;&amp;lt;&amp;lt;guix-file&amp;gt;&amp;gt;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#b8860b&#34;&gt;&amp;lt;&amp;lt;guix-srv&amp;gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#b8860b&#34;&gt;%base-home-services&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   (&lt;span style=&#34;color:#00a000&#34;&gt;packages&lt;/span&gt; (&lt;span style=&#34;color:#a2f&#34;&gt;map &lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;pkg&lt;/span&gt; (&lt;span style=&#34;color:#a2f&#34;&gt;list &lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;&amp;lt;&amp;lt;guix-pkg&amp;gt;&amp;gt;&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;channels&#34;&gt;Channels&lt;/h2&gt;
&lt;h3 id=&#34;guix&#34;&gt;guix&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;#+begin_src scheme :noweb-ref guix-channel
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;channel&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;name&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;&amp;#39;guix&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;url&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;https://git.guix.gnu.org/guix.git&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;branch&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;introduction&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#00a000&#34;&gt;make-channel-introduction&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;9edb3f66fd807b096b48283debdcddccfea34bad&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   (&lt;span style=&#34;color:#00a000&#34;&gt;openpgp-fingerprint&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;BBB0 2DDF 2CEA F6A8 0D1D  E643 A2A0 6DF2 A33A 54FA&amp;#34;&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;example-content&#34;&gt;Example content&lt;/h2&gt;
&lt;h3 id=&#34;package&#34;&gt;package&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;#+begin_src scheme :noweb-ref guix-pkg
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;emacs-next&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;emacs-org&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;service&#34;&gt;service&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;#+begin_src scheme :noweb-ref guix-srv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;service&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;home-dbus-service-type&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;simple-files&#34;&gt;simple files&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;#+begin_src scheme :noweb-ref guix-file
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;plain&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;,&lt;/span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;plain-file&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;file&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;hello, world&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;local&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;,&lt;/span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;local-file&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;.&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;file&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;:recursive?&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;#t&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;templated-files&#34;&gt;templated files&lt;/h3&gt;
&lt;p&gt;A &lt;code&gt;cfg&lt;/code&gt; source block with &lt;code&gt;:dest&lt;/code&gt; parameter will produce a result, which when wrapped using &lt;code&gt;:wrap &amp;quot;src scheme :noweb-ref guix-file&amp;quot;&lt;/code&gt;, would be weaved automatically in the main
template.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;#+begin_src cfg :dest &amp;#34;tmpl&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-cfg&#34; data-lang=&#34;cfg&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;this template gets converted to mixed-text-file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;ANT unicode characters mark scheme code&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;some-program&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;🐜 (pkg &amp;#34;msmtp&amp;#34;) 🐜/bin/msmtp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;tmpl&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;,&lt;/span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;mixed-text-file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;cfg-file&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;this template gets converted to mixed-text-file\n&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;ANT unicode characters mark scheme code\n&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;some-program = &amp;#34;&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;pkg&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;msmtp&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;/bin/msmtp&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;emacs-config&#34;&gt;Emacs config&lt;/h2&gt;
&lt;h3 id=&#34;ob-cfg-dot-el&#34;&gt;ob-cfg.el&lt;/h3&gt;
&lt;p&gt;A helper script that renders &lt;code&gt;cfg&lt;/code&gt; source code blocks.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;; -*- lexical-binding: t; -*-&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#a2f&#34;&gt;require&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;&amp;#39;rx&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#a2f&#34;&gt;defun&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;org-babel-execute:cfg&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;body&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;params&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Wrap BODY in a (mixed-text-file). If PARAMS contains :file, use its
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;contents instead of BODY. If PARAMS contain :chmod, additionally wrap
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;with (chmod-computed-file).&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#b8860b&#34;&gt;let-alist&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;params&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#a2f&#34;&gt;when&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;:file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#a2f&#34;&gt;with-temp-buffer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#b8860b&#34;&gt;insert-file-contents-literally&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;:file&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;nil&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#a2f&#34;&gt;setf&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;body&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;buffer-string&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#00a000&#34;&gt;concat&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;color:#a2f&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;:dest&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;format&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;(%S\n,&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;:dest&lt;/span&gt;) &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;color:#a2f&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;:chmod&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;(chmod-computed-file &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;(mixed-text-file\n  \&amp;#34;cfg-file\&amp;#34;\n&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;; split string into parts &amp;#39;string-part🐜scheme-part🐜&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;; - output each line of &amp;#39;string-part&amp;#39; quoted.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;; - output &amp;#39;scheme-part&amp;#39; as is&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;; - note: add an empty &amp;#39;scheme-part&amp;#39; at the end of input string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;;   so that the last &amp;#39;string-part&amp;#39; is matched&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;color:#b8860b&#34;&gt;replace-regexp-in-string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#a2f&#34;&gt;rx&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;minimal-match&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           (&lt;span style=&#34;color:#b8860b&#34;&gt;group&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;zero-or-more&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;anything&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#b44&#34;&gt;?🐜&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;group&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;zero-or-more&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;anything&lt;/span&gt;)) &lt;span style=&#34;color:#b44&#34;&gt;?🐜&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#a2f&#34;&gt;lambda&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;e&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#a2f&#34;&gt;let&lt;/span&gt; ((&lt;span style=&#34;color:#b8860b&#34;&gt;string-part&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;match-string&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;e&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;color:#b8860b&#34;&gt;scheme-part&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;match-string&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;e&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#00a000&#34;&gt;concat&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           (&lt;span style=&#34;color:#a2f&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;string-empty-p&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;string-part&lt;/span&gt;) &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;color:#b8860b&#34;&gt;string-join&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;color:#00a000&#34;&gt;mapcar&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               (&lt;span style=&#34;color:#a2f&#34;&gt;lambda&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;l&lt;/span&gt;) (&lt;span style=&#34;color:#00a000&#34;&gt;prin1-to-string&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;l&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;&amp;#39;&lt;/span&gt;((&lt;span style=&#34;color:#b8860b&#34;&gt;escape-newlines&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;t&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               (&lt;span style=&#34;color:#b8860b&#34;&gt;string-lines&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;string-part&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;t&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#b8860b&#34;&gt;scheme-part&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#00a000&#34;&gt;concat&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;body&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;🐜🐜&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#800&#34;&gt;t&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;t&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;color:#a2f&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;:chmod&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;format&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34; #o%o)&amp;#34;&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;org-babel-interpret-file-mode&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;:chmod&lt;/span&gt;)) &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     (&lt;span style=&#34;color:#a2f&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;:dest&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;)&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;config-package&#34;&gt;config package&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;#+begin_src scheme :noweb-ref emacs-config :noweb yes
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;package&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#00a000&#34;&gt;name&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;emacs-config&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#00a000&#34;&gt;version&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#00a000&#34;&gt;source&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;local-file&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;.&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;src&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;:recursive?&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;#t&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;; you really should put the files in git and enable filtering&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;; #:select? (git-predicate &amp;#34;.&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#00a000&#34;&gt;build-system&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;copy-build-system&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#00a000&#34;&gt;arguments&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#00a000&#34;&gt;list&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;:install-plan&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;((&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;.&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;:include&lt;/span&gt; (&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;.el&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;:phases&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#666&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;~&lt;/span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;modify-phases&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;%standard-phases&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#00a000&#34;&gt;add-before&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;&amp;#39;install&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;&amp;#39;tangle&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           (&lt;span style=&#34;color:#00a000&#34;&gt;lambda*&lt;/span&gt; (&lt;span style=&#34;color:#666&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;:key&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;inputs&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;:allow-other-keys&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;color:#00a000&#34;&gt;substitute*&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&amp;lt;&amp;lt;self()&amp;gt;&amp;gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               ((&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;\\(guix[/]pkg &amp;#39;([^ )]+)&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;pkg&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                (&lt;span style=&#34;color:#00a000&#34;&gt;format&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;#f&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;(concat ~s&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        (&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;or &lt;/span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;assoc-ref&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;inputs&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;pkg&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            (&lt;span style=&#34;color:#00a000&#34;&gt;error&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;format&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;#f&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;~a is required for emacs config but not present in inputs&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;pkg&lt;/span&gt;))))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;color:#00a000&#34;&gt;invoke&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;emacs&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;-Q&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;-l&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;ob-cfg.el&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;--batch&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;--eval&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                     (&lt;span style=&#34;color:#00a000&#34;&gt;simple-format&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;#f&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;~s&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                    &lt;span style=&#34;color:#666&#34;&gt;&amp;#39;&lt;/span&gt;(&lt;span style=&#34;color:#b8860b&#34;&gt;progn&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                      (&lt;span style=&#34;color:#00a000&#34;&gt;require&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;&amp;#39;ob-tangle&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                      (&lt;span style=&#34;color:#00a000&#34;&gt;setq&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;org-confirm-babel-evaluate&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;nil&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                      (&lt;span style=&#34;color:#00a000&#34;&gt;with-current-buffer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                       (&lt;span style=&#34;color:#00a000&#34;&gt;find-file-noselect&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&amp;lt;&amp;lt;self()&amp;gt;&amp;gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                       (&lt;span style=&#34;color:#00a000&#34;&gt;org-babel-tangle&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;early-init.el&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;elisp&amp;#34;&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;color:#00a000&#34;&gt;delete-file&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&amp;lt;&amp;lt;self()&amp;gt;&amp;gt;&amp;#34;&lt;/span&gt;))))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#00a000&#34;&gt;inputs&lt;/span&gt; (&lt;span style=&#34;color:#a2f&#34;&gt;map &lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;pkg&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;&amp;#39;&lt;/span&gt;(&lt;span style=&#34;color:#b8860b&#34;&gt;&amp;lt;&amp;lt;emacs-dep&amp;gt;&amp;gt;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#00a000&#34;&gt;native-inputs&lt;/span&gt; (&lt;span style=&#34;color:#a2f&#34;&gt;map &lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;pkg&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;&amp;#39;&lt;/span&gt;(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;emacs-org&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;emacs-next-minimal&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#00a000&#34;&gt;description&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;emacs config&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#00a000&#34;&gt;home-page&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;#f&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#00a000&#34;&gt;synopsis&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;#f&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#00a000&#34;&gt;license&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;#f&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;#+begin_src scheme :noweb-ref guix-file
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;.config/emacs&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;&amp;lt;&amp;lt;emacs-config&amp;gt;&amp;gt;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;config-parts&#34;&gt;config parts&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;#+begin_src text :noweb-ref emacs-dep
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;#34;msmtp&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;#+begin_src elisp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;load&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;concat&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;user-emacs-directory&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;ob-cfg.el&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#a2f&#34;&gt;require&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;&amp;#39;sendmail&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#a2f&#34;&gt;setq&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;sendmail-program&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;guix/pkg&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;&amp;#39;msmtp&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;/bin/msmtp&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    

    <item>
      <title>Pulumi &#43; SOPS</title>
      <link>http://sarg.org.ru/blog/pulumi-sops/</link>
      <pubDate>Tue, 17 Jun 2025 00:00:00 +0200</pubDate>
      <author>sarg@sarg.org.ru (Sergey Trofimov)</author>
      <guid>http://sarg.org.ru/blog/pulumi-sops/</guid>
      <description>&lt;p&gt;Secrets can be provided to Pulumi programs via environment variables,
configuration files, or Pulumi ESC. However, you might prefer to manage secrets
externally for use in other programs. While I use &lt;a href=&#34;https://www.passwordstore.org/&#34;&gt;pass&lt;/a&gt; for interactive secret
management, I use &lt;a href=&#34;https://getsops.io/&#34;&gt;SOPS&lt;/a&gt; for automation due to its text-based format and relative
simplicity.&lt;/p&gt;
&lt;p&gt;One method for passing secrets from SOPS is with the &lt;code&gt;sops exec-env&lt;/code&gt; command,
which adds secrets to the environment before executing a program. Pulumi can
then read them with &lt;code&gt;process.env[&amp;quot;TOKEN&amp;quot;]&lt;/code&gt;. However, this might return &lt;code&gt;null&lt;/code&gt;,
causing the program to fail or, worse, producing unintended resource changes
(e.g., setting a password to &lt;code&gt;null&lt;/code&gt; 😱).&lt;/p&gt;
&lt;p&gt;A superior approach leverages the structured (YAML) format in which SOPS stores
secrets. Extract a schema from the secret file and convert it to TypeScript
definitions:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;npm install quicktype
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sops -d --output-type json ../secrets.yaml | quicktype -t Secrets --lang ts &amp;gt; secrets.ts
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For convenience, add this invocation to &lt;code&gt;package.json&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;scripts&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;secrets&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;sops -d ...&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In your Pulumi program, read secrets from &lt;code&gt;SOPS&lt;/code&gt; and parse them into properly
typed classes:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-typescript&#34; data-lang=&#34;typescript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;import&lt;/span&gt; { Convert } &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;./secrets&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;import&lt;/span&gt; { execSync } &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;node:child_process&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;as&lt;/span&gt; cloudflare &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;@pulumi/cloudflare&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;const&lt;/span&gt; secretsJson &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; execSync(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;sops -d --output-type json ../secrets.yaml&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;const&lt;/span&gt; secrets &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; Convert.toSecrets(secretsJson.toString(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;utf8&amp;#39;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;const&lt;/span&gt; cloudflareProvider &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;new&lt;/span&gt; cloudflare.Provider(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;default&amp;#39;&lt;/span&gt;, {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  apiToken: &lt;span style=&#34;color:#0b0;font-weight:bold&#34;&gt;secrets.cloudflare.API_TOKEN&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Quicktype&amp;rsquo;s converter also validates the data, raising an error if a field is
missing. This eliminates unexpected &lt;code&gt;null&lt;/code&gt; values and improves the overall
structure of your program.&lt;/p&gt;
</description>
    </item>
    

    <item>
      <title>Self-hosted DynDNS</title>
      <link>http://sarg.org.ru/blog/diy-dyndns/</link>
      <pubDate>Mon, 16 Jun 2025 00:00:00 +0200</pubDate>
      <author>sarg@sarg.org.ru (Sergey Trofimov)</author>
      <guid>http://sarg.org.ru/blog/diy-dyndns/</guid>
      <description>&lt;p&gt;Roll your own free dynamic DNS (DynDNS) service with these simple steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Host your DNS zone with a provider offering API access.&lt;/li&gt;
&lt;li&gt;Deploy a DynDNS script to a FaaS platform.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For Cloudflare, follow these instructions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://developers.cloudflare.com/fundamentals/manage-domains/add-site/&#34;&gt;Add your domain to Cloudflare&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://developers.cloudflare.com/workers/get-started/guide/&#34;&gt;Set up your development environment&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Deploy the &lt;a href=&#34;https://github.com/sarg/dotfiles/tree/42a2f699bf91cd3e35f108203f0d882bf22e85d8/dyndns/&#34;&gt;DynDNS worker&lt;/a&gt;:
&lt;ul&gt;
&lt;li&gt;Obtain the worker script and run &lt;code&gt;npm i&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Modify the domain in &lt;code&gt;wrangler.jsonc&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Add subdomain tokens to &lt;code&gt;src/tokens.json&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Execute &lt;code&gt;wrangler deploy&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Verify operation with these commands:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Sets the A/AAAA record to the IP address from the request.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl https://dyndns.your.domain/your_token
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Explicitly sets the A/AAAA records.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl https://dyndns.your.domain/your_token?ipv4&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;1.2.3.4&amp;amp;&lt;span style=&#34;color:#b8860b&#34;&gt;ipv6&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;::1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Removes the A/AAAA records.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl -XDELETE https://dyndns.your.domain/your_token
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That&amp;rsquo;s all there is to it!&lt;/p&gt;
</description>
    </item>
    

    <item>
      <title>Cloudflare workers are cool</title>
      <link>http://sarg.org.ru/blog/cloudflare-workers/</link>
      <pubDate>Sun, 15 Jun 2025 00:00:00 +0200</pubDate>
      <author>sarg@sarg.org.ru (Sergey Trofimov)</author>
      <guid>http://sarg.org.ru/blog/cloudflare-workers/</guid>
      <description>&lt;p&gt;Writing a Telegram bot, my first option was to make it a Google Cloud Run
function. The bot is stateless and in its core is a simple webhook responder.
I quickly jotted down logic that only responded &amp;ldquo;Hello world&amp;rdquo; for every message.
Even though it was about ten lines of Python, it took a couple minutes to
deploy. I kind of expected that, knowing that Cloud Run functions are run in a
docker container and building these could be slow due to many network requests.
Cloud Run functions&amp;rsquo; response time also increases for the first request, as it
takes time to cold-start the container. Lastly, docker containers are bulky - a
hundred megabytes to run 10 lines of code is off-putting.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://workers.cloudflare.com/&#34;&gt;Cloudflare Workers&lt;/a&gt; on the other hand boast support for 0ms cold starts. It
turned out to be true, due to different approach they take. Instead of dedicated
clusters to run containerized functions, Cloudflare puts functions on edge
servers as &lt;a href=&#34;https://developers.cloudflare.com/workers/reference/how-workers-works/&#34;&gt;V8 Isolates&lt;/a&gt;. The cold start is eliminated because V8 Engine is
already running on the server. Deploying functions is also much faster, now that
there is no need to build a container. Granted, a build step is still present if
the program requires compilation (e.g. Typescript), but it is quick and happens
on my laptop. Only the code itself needs to be uploaded (a couple kilobytes), as
opposed to full runtime environment of a docker container.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sarg@thinkpad tgbot$ wrangler deploy --minify
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; ⛅️ wrangler 4.20.0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;───────────────────
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Total Upload: 22.12 KiB / gzip: 7.50 KiB
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Worker Startup Time: 14 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Uploaded tgbot (6.29 sec)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Deployed tgbot triggers (1.19 sec)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    

    <item>
      <title>On-demand Wireguard VPN server on Hetzner</title>
      <link>http://sarg.org.ru/blog/hetzner-vpn/</link>
      <pubDate>Fri, 13 Jun 2025 00:00:00 +0200</pubDate>
      <author>sarg@sarg.org.ru (Sergey Trofimov)</author>
      <guid>http://sarg.org.ru/blog/hetzner-vpn/</guid>
      <description>&lt;p&gt;I need VPN so rarely that any subscription service becomes cost-prohibitive.
Instead an on-demand VM instance could be provisioned in a cloud of choice. The
cheapest VM on &lt;a href=&#34;https://www.hetzner.com/de/cloud/&#34;&gt;Hetzner&lt;/a&gt; costs just 0.007 €/hr. Let&amp;rsquo;s make it real.&lt;/p&gt;
&lt;h2 id=&#34;generate-two-sets-of-keys-and-a-psk&#34;&gt;Generate two sets of keys and a PSK&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;for&lt;/span&gt; i in A B; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#b8860b&#34;&gt;KEY&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;$(&lt;/span&gt;wg genkey&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#b8860b&#34;&gt;PUB&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;$(&lt;/span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;$KEY&lt;/span&gt; | wg pubkey&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a2f&#34;&gt;echo&lt;/span&gt; -e &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$i&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt; key: &lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$KEY&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$i&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt; pub: &lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$PUB&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;  psk: &lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;$(&lt;/span&gt;wg genpsk&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;A key: 8LfzsPSUfKRIF1nJRGsWquwQfYK1t4xtZ/tZd0Iw/nc=
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;A pub: W3FavAFRpwbwrf+C1swigClVe5HV9deUwqv+V2vGhgc=
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;B key: 8LXWaEVGhHwPLnXjMjFpZwHNUfj9lfaKWdKB1/gRg3U=
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;B pub: Tt9VwSHn7v4k7FrdPcgfv6dpIQ+kl/lj1DUvGGnKj18=
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  psk: s34FX6nUoDOiPzj6ExWh92kgA03xk6YaQtf7qTRRO2M=
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Put these in &lt;code&gt;{ placeholders }&lt;/code&gt; in files below.&lt;/p&gt;
&lt;h2 id=&#34;prepare-a-cloud-init-provision-script&#34;&gt;Prepare a &lt;code&gt;cloud-init&lt;/code&gt; provision script&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&#34;https://docs.cloud-init.io/en/latest/reference/modules.html#wireguard&#34;&gt;wireguard&lt;/a&gt; module is only supported on &lt;code&gt;ubuntu&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#cloud-config&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;wireguard&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;interfaces&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;wg0&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;config_path&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;/etc/wireguard/wg0.conf&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;content&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;|&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        [Interface]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        Address = 10.66.66.1/24,fd42:42:42::1/64
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        ListenPort = 52817
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        PrivateKey = { A key }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        PostUp = iptables -I INPUT -p udp --dport 52817 -j ACCEPT
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        PostUp = iptables -I FORWARD -i eth0 -o wg0 -j ACCEPT
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        PostUp = iptables -I FORWARD -i wg0 -j ACCEPT
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        PostUp = ip6tables -I FORWARD -i wg0 -j ACCEPT
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        PostUp = ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        PostDown = iptables -D INPUT -p udp --dport 52817 -j ACCEPT
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        PostDown = iptables -D FORWARD -i eth0 -o wg0 -j ACCEPT
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        PostDown = ip6tables -D FORWARD -i wg0 -j ACCEPT
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        PostDown = ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        [Peer]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        PublicKey = { B pub }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        PresharedKey = { psk }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;        AllowedIPs = 10.66.66.2/32,fd42:42:42::2/128&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;runcmd&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- sysctl -p /etc/sysctl.d/nat.conf&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;write_files&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;content&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;|&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;      net.ipv4.ip_forward = 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44;font-style:italic&#34;&gt;      net.ipv6.conf.all.forwarding = 1&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;owner&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;root:root&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;path&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;/etc/sysctl.d/nat.conf&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;permissions&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;0644&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;deploy-the-vm&#34;&gt;Deploy the VM&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hcloud server create --name vpn &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    --type cax11 --image ubuntu-24.04 &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    --location hel1 &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    --ssh-key thinkpad &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    --start-after-create
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Server 65612345 created
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;IPv4: 123.123.123.123
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;prepare-client-config&#34;&gt;Prepare client config&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;[Interface]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;Address&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;10.66.66.2/32, fd42:42:42::2/128&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;PrivateKey&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;{ B key }&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;ListenPort&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;51820&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;[Peer]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;PublicKey&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;{ A pub }&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;PresharedKey&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;{ psk }&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;AllowedIPs&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;0.0.0.0/0, ::/0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;Endpoint&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;{ VM ip }&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;start-wireguard&#34;&gt;Start Wireguard&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo wg-quick up ./wg0.conf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;cleanup-after-use&#34;&gt;Cleanup after use&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo wg-quick down ./wg0.conf
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hcloud server delete vpn
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Server vpn deleted
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;further-reading&#34;&gt;Further reading&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://wiki.archlinux.org/title/Wireguard&#34;&gt;https://wiki.archlinux.org/title/Wireguard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.cloud-init.io/en/latest/index.html&#34;&gt;https://docs.cloud-init.io/en/latest/index.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/hetznercloud/cli&#34;&gt;https://github.com/hetznercloud/cli&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    

    <item>
      <title>Trying Pulumi</title>
      <link>http://sarg.org.ru/blog/iac-taste/</link>
      <pubDate>Fri, 13 Jun 2025 00:00:00 +0200</pubDate>
      <author>sarg@sarg.org.ru (Sergey Trofimov)</author>
      <guid>http://sarg.org.ru/blog/iac-taste/</guid>
      <description>&lt;p&gt;I finally described my cloud infrastructure in a declarative configuration. It&amp;rsquo;s
a modest setup: a DNS zone, this blog, and a couple of VM instances. Terraform,
which I use at work, was my initial choice. I quickly imported the existing
resources, but the resulting code didn&amp;rsquo;t spark joy. It felt too verbose and
lacked expressiveness. HCL still relies on &lt;code&gt;for_each&lt;/code&gt; and &lt;code&gt;count&lt;/code&gt; for even basic
flow control.&lt;/p&gt;
&lt;p&gt;Looking for alternatives, I chose Pulumi because it supports configuration in
general-purpose programming languages like Typescript, Go, or Java. Lisp
dialects weren&amp;rsquo;t supported, so I settled on Typescript. Emacs with LSP support
provided a great developer experience, offering contextual autocomplete and easy
access to comprehensive documentation.&lt;/p&gt;
&lt;p&gt;For secrets management, Pulumi offers ESC, which requires account registration
and is dependent on their cloud. Since I don&amp;rsquo;t need RBAC or anything complex, I
replaced it with &lt;a href=&#34;https://getsops.io/&#34;&gt;SOPS&lt;/a&gt;. A small helper script (&lt;a href=&#34;https://github.com/sarg/dotfiles/tree/01b3e53da54dbef83777f190dca15964fda1c1ab/sops/.config/direnv/lib/sops.sh&#34;&gt;direnv/lib/sops.sh&lt;/a&gt;) injects the
secrets into the shell environment when I &lt;code&gt;cd&lt;/code&gt; into the &lt;code&gt;pulumi&lt;/code&gt; directory.&lt;/p&gt;
&lt;p&gt;Pulumi is a clear winner for me. Writing infrastructure code in a proper
language is liberating, and I appreciate how &lt;code&gt;pulumi stack&lt;/code&gt; neatly organizes my
infrastructure view.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Current stack is dev:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Managed by thinkpad
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Last updated: 59 minutes ago (2025-06-13 07:42:44.338221653 +0200 CEST)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Pulumi version used: v3.175.0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Current stack resources (40):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    TYPE                                                            NAME
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pulumi:pulumi:Stack                                             terraform-dev
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├─ components:index:Cloudflare                                  cloudflare
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  ├─ cloudflare:index/zone:Zone                                sarg.org.ru
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  │  ├─ cloudflare:index/dnsRecord:DnsRecord                   MX 2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  │  ├─ cloudflare:index/dnsRecord:DnsRecord                   CNAME mail
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  │  ├─ cloudflare:index/dnsRecord:DnsRecord                   MX 3
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  │  ├─ cloudflare:index/dnsRecord:DnsRecord                   TXT dmarc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  │  ├─ cloudflare:index/dnsRecord:DnsRecord                   MX 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  │  ├─ cloudflare:index/dnsRecord:DnsRecord                   TXT spf
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  │  ├─ cloudflare:index/dnsRecord:DnsRecord                   MX 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  │  └─ cloudflare:index/dnsRecord:DnsRecord                   TXT dkim
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  ├─ cloudflare:index/workersScript:WorkersScript              blog
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  ├─ cloudflare:index/workersScript:WorkersScript              tgbot
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  ├─ cloudflare:index/workersCustomDomain:WorkersCustomDomain  blog
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  └─ cloudflare:index/workersCustomDomain:WorkersCustomDomain  tgbot
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├─ components:index:Google                                      google
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  ├─ gcp:organizations/project:Project                         default
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  ├─ gcp:projects/service:Service                              services-apikeys.googleapis.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  ├─ gcp:projects/service:Service                              services-serviceusage.googleapis.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  ├─ gcp:projects/service:Service                              services-generativelanguage.googleapis.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  ├─ gcp:projects/service:Service                              services-cloudresourcemanager.googleapis.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  └─ gcp:projects/apiKey:ApiKey                                gptel
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├─ components:index:Selectel                                    selectel
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  ├─ openstack:networking/network:Network                      private
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  ├─ openstack:compute/keypair:Keypair                         ssh_key
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  ├─ openstack:networking/subnet:Subnet                        private
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  ├─ openstack:networking/router:Router                        router
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  ├─ openstack:networking/port:Port                            vpn
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  └─ openstack:networking/routerInterface:RouterInterface      interface
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├─ components:index:Hetzner                                     hetzner
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  ├─ hcloud:index/sshKey:SshKey                                ssh_key
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  └─ hcloud:index/primaryIp:PrimaryIp                          vpn_ipv6
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├─ pulumi:providers:telegram                                    telegram
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├─ components:index:Telegram                                    telegram
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  ├─ telegram:index/botCommands:BotCommands                    diogenisbot
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    │  └─ telegram:index/botWebhook:BotWebhook                      diogenisbot
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├─ pulumi:providers:openstack                                   default_5_1_0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├─ pulumi:providers:hcloud                                      default_1_23_0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├─ pulumi:providers:cloudflare                                  default_6_2_1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    └─ pulumi:providers:gcp                                         default_8_33_0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Current stack outputs (0):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    No output values currently in this stack
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Use `pulumi stack select` to change stack; `pulumi stack ls` lists known ones
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    

    <item>
      <title>Following git changelogs in elfeed</title>
      <link>http://sarg.org.ru/blog/git2atom/</link>
      <pubDate>Sat, 08 Feb 2025 00:00:00 +0100</pubDate>
      <author>sarg@sarg.org.ru (Sergey Trofimov)</author>
      <guid>http://sarg.org.ru/blog/git2atom/</guid>
      <description>&lt;p&gt;I wanted a simple solution to read daily commit logs of the repos I follow,
but couldn&amp;rsquo;t find any. For a while I resorted to an &lt;code&gt;org-mode&lt;/code&gt; block that I had
to execute time to time:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#+begin_src &lt;/span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;sh&lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; :results drawer :var repo=&amp;#39;guix&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;cd&lt;/span&gt; ~/devel/ext/&lt;span style=&#34;color:#b8860b&#34;&gt;$repo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git fetch origin master
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git show-branch _track &amp;gt; /dev/null &lt;span style=&#34;color:#666&#34;&gt;||&lt;/span&gt; git branch -f _track origin/master~20
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git log --date&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;short --pretty&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;%ad %s&amp;#39;&lt;/span&gt; _track..origin/master
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git branch -f _track origin/master &amp;gt; /dev/null
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#+end_src&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But quickly it started bothering me and I&amp;rsquo;ve jotted down a &lt;a href=&#34;https://github.com/babashka/babashka&#34;&gt;Babashka&lt;/a&gt; script that
does the same:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;!/usr/bin/env&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;bb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;ns &lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;git2rss&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#b8860b&#34;&gt;:require&lt;/span&gt; [&lt;span style=&#34;color:#b8860b&#34;&gt;clojure.zip&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;zip&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            [&lt;span style=&#34;color:#b8860b&#34;&gt;clojure.string&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;str&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            [&lt;span style=&#34;color:#b8860b&#34;&gt;clojure.java.shell&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;shell&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            [&lt;span style=&#34;color:#b8860b&#34;&gt;clojure.data.xml&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;xml&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            [&lt;span style=&#34;color:#b8860b&#34;&gt;clojure.java.io&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;:as&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;io&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            [&lt;span style=&#34;color:#b8860b&#34;&gt;clojure.data.zip.xml&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;:refer&lt;/span&gt; [&lt;span style=&#34;color:#b8860b&#34;&gt;xml1-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;text&lt;/span&gt;]]))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;defn &lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;commits-for&lt;/span&gt; [&lt;span style=&#34;color:#b8860b&#34;&gt;gitdir&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;last-seen&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;before&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#00a000&#34;&gt;-&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;shell/with-sh-dir&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;gitdir&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#00a000&#34;&gt;shell/sh&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;git&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;fetch&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;origin&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#00a000&#34;&gt;shell/sh&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;git&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;log&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   (&lt;span style=&#34;color:#a2f&#34;&gt;str &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;--format=%H%n%an%n%cI%n%s&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   (&lt;span style=&#34;color:#a2f&#34;&gt;str &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;--before=&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;before&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;T00:00:00Z&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   (&lt;span style=&#34;color:#a2f&#34;&gt;str &lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;last-seen&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;..origin/master&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &lt;span style=&#34;color:#b8860b&#34;&gt;:out&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &lt;span style=&#34;color:#b8860b&#34;&gt;str/split-lines&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;color:#00a000&#34;&gt;partition&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;4&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       (&lt;span style=&#34;color:#a2f&#34;&gt;map &lt;/span&gt;(&lt;span style=&#34;color:#a2f&#34;&gt;partial zipmap &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;&amp;#39;&lt;/span&gt;(&lt;span style=&#34;color:#b8860b&#34;&gt;:commit&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;:author&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;:date&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;:subject&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;let*&lt;/span&gt; [&lt;span style=&#34;color:#b8860b&#34;&gt;filename&lt;/span&gt; (&lt;span style=&#34;color:#a2f&#34;&gt;first &lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;*command-line-args*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &lt;span style=&#34;color:#b8860b&#34;&gt;now&lt;/span&gt; (&lt;span style=&#34;color:#a2f&#34;&gt;-&amp;gt; &lt;/span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;java.time.Instant/now&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               (&lt;span style=&#34;color:#00a000&#34;&gt;.truncatedTo&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;java.time.temporal.ChronoUnit/SECONDS&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &lt;span style=&#34;color:#b8860b&#34;&gt;yesterday&lt;/span&gt; (&lt;span style=&#34;color:#a2f&#34;&gt;-&amp;gt; &lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;now&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                     (&lt;span style=&#34;color:#00a000&#34;&gt;.atZone&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;java.time.ZoneOffset/UTC&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                     &lt;span style=&#34;color:#b8860b&#34;&gt;.toLocalDate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                     (&lt;span style=&#34;color:#00a000&#34;&gt;.minusDays&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;1&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &lt;span style=&#34;color:#b8860b&#34;&gt;feed&lt;/span&gt; (&lt;span style=&#34;color:#a2f&#34;&gt;-&amp;gt; &lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;filename&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#b8860b&#34;&gt;io/reader&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                (&lt;span style=&#34;color:#00a000&#34;&gt;xml/parse&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;:namespace-aware&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                           &lt;span style=&#34;color:#b8860b&#34;&gt;:skip-whitespace&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;true&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#b8860b&#34;&gt;zip/xml-zip&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;; state from the input file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &lt;span style=&#34;color:#b8860b&#34;&gt;last-seen&lt;/span&gt; (&lt;span style=&#34;color:#a2f&#34;&gt;or &lt;/span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;xml1-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;feed&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;:git2rss&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;:last-seen&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;text&lt;/span&gt;) &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;origin/master~10&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &lt;span style=&#34;color:#b8860b&#34;&gt;gitdir&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;xml1-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;feed&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;:git2rss&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;:dir&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;text&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &lt;span style=&#34;color:#b8860b&#34;&gt;commit-url&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;xml1-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;feed&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;:git2rss&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;:commit-url&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;text&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       &lt;span style=&#34;color:#b8860b&#34;&gt;range-url&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;xml1-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;feed&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;:git2rss&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;:range-url&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;text&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;def &lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;commits&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;commits-for&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;gitdir&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;last-seen&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;.plusDays&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;yesterday&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;1&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#a2f&#34;&gt;println &lt;/span&gt;(&lt;span style=&#34;color:#a2f&#34;&gt;count &lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;commits&lt;/span&gt;) &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34; new commits.&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#a2f&#34;&gt;when &lt;/span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;empty?&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;commits&lt;/span&gt;) (&lt;span style=&#34;color:#00a000&#34;&gt;System/exit&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;0&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;def &lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;latest-commit&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;:commit&lt;/span&gt; (&lt;span style=&#34;color:#a2f&#34;&gt;first &lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;commits&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;def &lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;new-entry&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#00a000&#34;&gt;xml/sexp-as-element&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     [&lt;span style=&#34;color:#b8860b&#34;&gt;:entry&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      [&lt;span style=&#34;color:#b8860b&#34;&gt;:title&lt;/span&gt; (&lt;span style=&#34;color:#a2f&#34;&gt;str &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Commits for &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;yesterday&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      [&lt;span style=&#34;color:#b8860b&#34;&gt;:id&lt;/span&gt; (&lt;span style=&#34;color:#a2f&#34;&gt;str &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;urn:git2rss:&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;yesterday&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      [&lt;span style=&#34;color:#b8860b&#34;&gt;:link&lt;/span&gt; {&lt;span style=&#34;color:#b8860b&#34;&gt;:rel&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;alternate&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#b8860b&#34;&gt;:href&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;format&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;range-url&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;last-seen&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;latest-commit&lt;/span&gt;)}]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      [&lt;span style=&#34;color:#b8860b&#34;&gt;:updated&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;now&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      [&lt;span style=&#34;color:#b8860b&#34;&gt;:content&lt;/span&gt; {&lt;span style=&#34;color:#b8860b&#34;&gt;:type&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;xhtml&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       [&lt;span style=&#34;color:#b8860b&#34;&gt;:div&lt;/span&gt; {&lt;span style=&#34;color:#b8860b&#34;&gt;:xmlns&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;http://www.w3.org/1999/xhtml&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        [&lt;span style=&#34;color:#b8860b&#34;&gt;:p&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Commits&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         [&lt;span style=&#34;color:#b8860b&#34;&gt;:ul&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#a2f&#34;&gt;for &lt;/span&gt;[&lt;span style=&#34;color:#b8860b&#34;&gt;c&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;commits&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            [&lt;span style=&#34;color:#b8860b&#34;&gt;:li&lt;/span&gt; [&lt;span style=&#34;color:#b8860b&#34;&gt;:a&lt;/span&gt; {&lt;span style=&#34;color:#b8860b&#34;&gt;:href&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;format&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;commit-url&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;:commit&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;c&lt;/span&gt;))} (&lt;span style=&#34;color:#b8860b&#34;&gt;:subject&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;c&lt;/span&gt;)]])]]]]]))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#00a000&#34;&gt;spit&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;filename&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#a2f&#34;&gt;-&amp;gt; &lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;feed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            (&lt;span style=&#34;color:#00a000&#34;&gt;xml1-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;:updated&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            (&lt;span style=&#34;color:#00a000&#34;&gt;zip/replace&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;xml/element&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;:updated&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;nil&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;.toString&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;now&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#b8860b&#34;&gt;zip/up&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            (&lt;span style=&#34;color:#00a000&#34;&gt;xml1-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;:git2rss&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;:last-seen&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            (&lt;span style=&#34;color:#00a000&#34;&gt;zip/replace&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;xml/element&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;:last-seen&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;latest-commit&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#b8860b&#34;&gt;zip/up&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#b8860b&#34;&gt;zip/rightmost&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            (&lt;span style=&#34;color:#00a000&#34;&gt;zip/insert-right&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;new-entry&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#b8860b&#34;&gt;zip/root&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#b8860b&#34;&gt;xml/indent-str&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The last touch was to register a scheduled job in &lt;a href=&#34;https://github.com/sarg/dotfiles/commit/0ee195be&#34;&gt;Guix configuration&lt;/a&gt; and to fix
&lt;code&gt;file://&lt;/code&gt; style link support in &lt;a href=&#34;https://github.com/remyhonig/elfeed-org/commit/1197cf29f6604e572ec604874a8f50b58081176a&#34;&gt;elfeed-org&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;And voila:
&lt;img src=&#34;http://sarg.org.ru/ox-hugo/elfeed-git2rss.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
</description>
    </item>
    

    <item>
      <title>Self-hosted org-mode tools</title>
      <link>http://sarg.org.ru/blog/org-mode-tools/</link>
      <pubDate>Thu, 09 Jan 2025 00:00:00 +0100</pubDate>
      <author>sarg@sarg.org.ru (Sergey Trofimov)</author>
      <guid>http://sarg.org.ru/blog/org-mode-tools/</guid>
      <description>&lt;p&gt;I have a couple org-mode based tools now:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://sarg.org.ru/blog/export-youtube-liked/&#34;&gt;youtube.org&lt;/a&gt; for saving liked videos&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://sarg.org.ru/blog/org-watchlist/&#34;&gt;movies.org&lt;/a&gt; to keep a log of watched movies&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://sarg.org.ru/blog/emacs-hugo/&#34;&gt;blog.org&lt;/a&gt; for this blog&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://sarg.org.ru/books/&#34;&gt;books.org&lt;/a&gt; to keep a reading log&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each of these has an &lt;code&gt;API&lt;/code&gt; heading that defines interactive helpers relevant for
the file. E.g.:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt; COMMENT&lt;/span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt; API&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;#+NAME&lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;: api&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#+begin_src &lt;/span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;elisp&lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#a2f&#34;&gt;define-minor-mode&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;org-books-mode&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Helper functions for books.org&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a2f&#34;&gt;:interactive&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a2f&#34;&gt;:keymap&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;list&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           (&lt;span style=&#34;color:#00a000&#34;&gt;cons&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;kbd&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;C-c C-o&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#00a000&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;org-books-open-goodreads&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#a2f&#34;&gt;defun&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;org-books-open-goodreads&lt;/span&gt; ()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Open goodreads for current entry.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#a2f&#34;&gt;interactive&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;&amp;#39;org-books-mode&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#b8860b&#34;&gt;browse-url&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;format&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;https://goodreads.com/book/show/%s&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                      (&lt;span style=&#34;color:#b8860b&#34;&gt;cdar&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;org-entry-properties&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;goodreadsid&amp;#34;&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#b8860b&#34;&gt;org-books-mode&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#+end_src&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Local Variables:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# eval: (sarg/eval-org-src-block &amp;#34;api&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# End:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;Code Snippet 1:&lt;/span&gt;
  API section
&lt;/div&gt;
&lt;p&gt;Where &lt;code&gt;sarg/eval-org-src-block&lt;/code&gt; is defined as:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#a2f&#34;&gt;defun&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;sarg/eval-org-src-block&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;name&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Eval elisp block NAME. To be used in org files in Local variables section.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#a2f&#34;&gt;save-excursion&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#b8860b&#34;&gt;org-babel-goto-named-src-block&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;name&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#a2f&#34;&gt;let*&lt;/span&gt; ((&lt;span style=&#34;color:#b8860b&#34;&gt;block-info&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;org-babel-get-src-block-info&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           (&lt;span style=&#34;color:#b8860b&#34;&gt;lang&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;nth&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;block-info&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           (&lt;span style=&#34;color:#b8860b&#34;&gt;body&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;nth&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;block-info&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#a2f&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a2f&#34;&gt;or&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;string=&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;lang&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;emacs-lisp&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              (&lt;span style=&#34;color:#b8860b&#34;&gt;string=&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;lang&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;elisp&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#a2f&#34;&gt;cl-loop&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;with&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;next&lt;/span&gt; &lt;span style=&#34;color:#00a000&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   &lt;span style=&#34;color:#b8860b&#34;&gt;with&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;maxlen&lt;/span&gt; &lt;span style=&#34;color:#00a000&#34;&gt;=&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;length&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;body&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   &lt;span style=&#34;color:#b8860b&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;sexp&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;next&lt;/span&gt;) &lt;span style=&#34;color:#00a000&#34;&gt;=&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;read-from-string&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;body&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;next&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   &lt;span style=&#34;color:#a2f&#34;&gt;do&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;eval&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;sexp&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   &lt;span style=&#34;color:#a2f&#34;&gt;while&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;next&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;maxlen&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#d2413a;font-weight:bold&#34;&gt;error&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;%s is not an emacs-lisp src block&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;name&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;Code Snippet 2:&lt;/span&gt;
  sarg/eval-org-src-block
&lt;/div&gt;
&lt;p&gt;This way when such org file is opened, the API code block gets loaded and a
buffer-local minor mode gets activated. The mode is marked as &lt;code&gt;:interactive nil&lt;/code&gt;
so it doesn&amp;rsquo;t pollute &lt;code&gt;M-x&lt;/code&gt;. Helper functions are restricted to this mode as
well with &lt;code&gt;(interactive nil &#39;org-books-mode)&lt;/code&gt;. I like that such an &amp;ldquo;API&amp;rdquo; is
contained in the file itself, making it a kind of self-hosted program.&lt;/p&gt;
</description>
    </item>
    

    <item>
      <title>Reprovisioning Guix on a new machine</title>
      <link>http://sarg.org.ru/blog/guix-restore-drill/</link>
      <pubDate>Wed, 15 Mar 2023 00:00:00 +0100</pubDate>
      <author>sarg@sarg.org.ru (Sergey Trofimov)</author>
      <guid>http://sarg.org.ru/blog/guix-restore-drill/</guid>
      <description>&lt;style&gt;
.src-block-number {
  display: none;
}
.src-block-caption {
  text-align: center;
}
&lt;/style&gt;
&lt;p&gt;No matter how often you backup, if you never test your recovery procedures -
you&amp;rsquo;d be surprised when it comes to it. So let&amp;rsquo;s make a recovery plan and give
it a test.&lt;/p&gt;
&lt;h2 id=&#34;back-up-user-files&#34;&gt;Back up user files&lt;/h2&gt;
&lt;p&gt;Having &lt;a href=&#34;https://github.com/sarg/dotfiles/blob/01b3e53da54dbef83777f190dca15964fda1c1ab/guix/home.scm#L265-L276&#34;&gt;configured&lt;/a&gt; &lt;code&gt;restic-backup-service&lt;/code&gt;, it&amp;rsquo;s just one command:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;restic-guix backup storage
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;disaster-happens&#34;&gt;Disaster happens&lt;/h2&gt;
&lt;p&gt;I see two options:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I just need to move my digital stuff to a new machine.&lt;/li&gt;
&lt;li&gt;I&amp;rsquo;ve lost access to my current machine.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let&amp;rsquo;s follow the first option for now and prepare everything to migrate smoothly.&lt;/p&gt;
&lt;h2 id=&#34;make-a-raw-disk-image&#34;&gt;Make a raw disk image&lt;/h2&gt;
&lt;p&gt;That&amp;rsquo;s as simple as running &lt;code&gt;guix system image&lt;/code&gt;. The only trick is to add a
couple more services to the &lt;code&gt;operating-system&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-scheme&#34; data-lang=&#34;scheme&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;use-modules&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;gnu&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;color:#00a000&#34;&gt;gnu&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;system&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;color:#00a000&#34;&gt;gnu&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;services&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;admin&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;color:#00a000&#34;&gt;gnu&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;services&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;guix&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;color:#00a000&#34;&gt;ice-9&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;textual-ports&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;define &lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;system&lt;/span&gt; (&lt;span style=&#34;color:#a2f&#34;&gt;load &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;./system.scm&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;define &lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;root-fs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#00a000&#34;&gt;first&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;filter&lt;/span&gt; (&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;lambda &lt;/span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;fs&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   (&lt;span style=&#34;color:#a2f&#34;&gt;string=? &lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;/&amp;#34;&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;file-system-mount-point&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;fs&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;color:#00a000&#34;&gt;operating-system-file-systems&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;system&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;operating-system&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#00a000&#34;&gt;inherit&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;system&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#00a000&#34;&gt;services&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;cons*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;; auto-resize fs on boot&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;color:#00a000&#34;&gt;service&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;resize-file-system-service-type&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                      (&lt;span style=&#34;color:#00a000&#34;&gt;resize-file-system-configuration&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                       (&lt;span style=&#34;color:#00a000&#34;&gt;file-system&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;root-fs&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;color:#00a000&#34;&gt;simple-service&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;&amp;#39;activate-storage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                             &lt;span style=&#34;color:#b8860b&#34;&gt;activation-service-type&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                             &lt;span style=&#34;color:#666&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;~&lt;/span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;begin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                 (&lt;span style=&#34;color:#00a000&#34;&gt;use-modules&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;guix&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;build&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;utils&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                 (&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;let &lt;/span&gt;((&lt;span style=&#34;color:#00a000&#34;&gt;dir&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;/storage&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                       (&lt;span style=&#34;color:#00a000&#34;&gt;%user&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;getpw&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;sarg&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                   (&lt;span style=&#34;color:#00a000&#34;&gt;mkdir-p&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;dir&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                   (&lt;span style=&#34;color:#00a000&#34;&gt;chown&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;dir&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;passwd:uid&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;%user&lt;/span&gt;) (&lt;span style=&#34;color:#00a000&#34;&gt;passwd:gid&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;%user&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                   (&lt;span style=&#34;color:#00a000&#34;&gt;chmod&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;dir&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;o700&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;; restore /storage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;; (simple-service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;;  &amp;#39;restore-storage-from-backup shepherd-root-service-type&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;;  (list (shepherd-service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;;         (requirement &amp;#39;(user-processes file-systems file-system-/media/500GB))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;;         (start #~(lambda _ (invoke #$(file-append restic &amp;#34;/bin/restic&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;;                                    &amp;#34;-r&amp;#34; &amp;#34;/media/500GB/restic&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;;                                    &amp;#34;-p&amp;#34; &amp;#34;/media/500GB/restic/pass&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;;                                    &amp;#34;restore&amp;#34; &amp;#34;latest&amp;#34;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;;         (stop #f))))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;; install user profile&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;; (service guix-home-service-type&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;;          `((&amp;#34;sarg&amp;#34; ,(load &amp;#34;./home.scm&amp;#34;))))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             (&lt;span style=&#34;color:#00a000&#34;&gt;operating-system-user-services&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;system&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;Code Snippet 1:&lt;/span&gt;
  system-image.scm
&lt;/div&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;guix system image --image-type&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;efi-raw system-image.scm
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;The following derivations will be built:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  /gnu/store/q0gvw0s79wkjlanfq4yjjyf2f9ddk4iq-disk-image.drv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  /gnu/store/dp0p01bzgb9aarzx040iv7k5w1r7z5xx-genimage.cfg.drv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  /gnu/store/kr39hrsyvwp17ny5hcrj6ynfn56i2cq8-partition.img.drv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  /gnu/store/758yrvd3m7016i5vflzjyg9232j75k2r-system.drv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  /gnu/store/58xsyrsaqaqh3dsxzb7zc0h72v7ha3as-etc.drv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  /gnu/store/5kifgf0yqnki7k9wg0a8jlviqibirmxy-activate.scm.drv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  /gnu/store/rqyl2kcj5q84daw4qriza38l0vkrax0m-activate-service.scm.drv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  /gnu/store/5lnmmgrgpy58nnkcpy8z22a0kf54yv0k-boot.drv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  /gnu/store/ri65rz6rgh5kv6ff8g2q313fr9fjd5ac-provenance.drv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  /gnu/store/z62g9qwy9k65awaaxg2f3jzdadsk5iha-grub.cfg.drv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  /gnu/store/x1zyd14c5xnpd51ql6bcfdv0q06nla8a-partition.img.drv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;building /gnu/store/ri65rz6rgh5kv6ff8g2q313fr9fjd5ac-provenance.drv...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;building /gnu/store/58xsyrsaqaqh3dsxzb7zc0h72v7ha3as-etc.drv...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;building /gnu/store/rqyl2kcj5q84daw4qriza38l0vkrax0m-activate-service.scm.drv...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;building /gnu/store/5kifgf0yqnki7k9wg0a8jlviqibirmxy-activate.scm.drv...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;building /gnu/store/5lnmmgrgpy58nnkcpy8z22a0kf54yv0k-boot.drv...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;building /gnu/store/758yrvd3m7016i5vflzjyg9232j75k2r-system.drv...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;building /gnu/store/z62g9qwy9k65awaaxg2f3jzdadsk5iha-grub.cfg.drv...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;building /gnu/store/kr39hrsyvwp17ny5hcrj6ynfn56i2cq8-partition.img.drv...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;building /gnu/store/x1zyd14c5xnpd51ql6bcfdv0q06nla8a-partition.img.drv...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;building /gnu/store/dp0p01bzgb9aarzx040iv7k5w1r7z5xx-genimage.cfg.drv...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;building /gnu/store/q0gvw0s79wkjlanfq4yjjyf2f9ddk4iq-disk-image.drv...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And the disk image is: &lt;code&gt;/gnu/store/rj2i98lw7vjj0k48dbwfs0q9aqnd9nxk-disk-image&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s check its partition table:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fdisk -l &lt;span style=&#34;color:#b8860b&#34;&gt;$disk_image&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Disk /gnu/store/rj2i98lw7vjj0k48dbwfs0q9aqnd9nxk-disk-image: 2.32 GiB, 2488737792 bytes, 4860816 sectors
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Units: sectors of 1 * 512 = 512 bytes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Sector size (logical/physical): 512 bytes / 512 bytes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;I/O size (minimum/optimal): 512 bytes / 512 bytes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Disklabel type: gpt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Disk identifier: 389B45C2-0EC7-42EC-9D96-49B40F820311
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Device                                                  Start     End Sectors  Size Type
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/gnu/store/rj2i98lw7vjj0k48dbwfs0q9aqnd9nxk-disk-image1  2048   83967   81920   40M EFI System
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/gnu/store/rj2i98lw7vjj0k48dbwfs0q9aqnd9nxk-disk-image2 83968 4860775 4776808  2.3G Linux filesystem
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And filesystems labels are:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;alias&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;kpartx&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;$(&lt;/span&gt;guix build multipath-tools&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;)&lt;/span&gt;/sbin/kpartx
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kpartx -av &lt;span style=&#34;color:#b8860b&#34;&gt;$disk_image&lt;/span&gt; &amp;gt;/dev/null
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lsblk -o NAME,FSTYPE,FSVER,LABEL,UUID /dev/loop0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kpartx -d &lt;span style=&#34;color:#b8860b&#34;&gt;$disk_image&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NAME      FSTYPE FSVER LABEL      UUID
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;loop0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;|-loop0p1 vfat   FAT16 GNU-ESP    572A-DDF3
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;`-loop0p2 ext4   1.0   Guix_image f6bc8ad8-ff1a-1754-eb2b-35d0f6bc8ad8
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that the partition labels chosen by &lt;code&gt;guix system image&lt;/code&gt; are not taken from
the &lt;code&gt;operating-system&lt;/code&gt; definition. They&amp;rsquo;re hardcoded in the &lt;code&gt;guix&lt;/code&gt; sources and
therefore I have to hardcode the same values in my &lt;code&gt;operating-system&lt;/code&gt;. Without
matching labels the system would just refuse to boot as they&amp;rsquo;re used in the EFI
loader to find the boot partition and also in the &lt;code&gt;fstab&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LABEL=Guix_image  /      ext4  defaults
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LABEL=GNU-ESP     /boot  vfat  defaults
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;putting-disk-image-on-a-real-machine&#34;&gt;Putting disk image on a real machine&lt;/h2&gt;
&lt;p&gt;I have a &lt;a href=&#34;https://www.ventoy.net/en/index.html&#34;&gt;Ventoy&lt;/a&gt; USB stick with &lt;a href=&#34;https://lubuntu.me/downloads/&#34;&gt;Lubuntu Live CD&lt;/a&gt; on it. Let&amp;rsquo;s just copy the
resulting image to the stick. Note, you might need to follow this recipe: &lt;a href=&#34;https://github.com/ventoy/Ventoy/issues/79&#34;&gt;Access
USB stick on live ISO&lt;/a&gt; as by default the USB drive will not be accessible.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;eval&lt;/span&gt; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;$(&lt;/span&gt;lsblk -P -o LABEL,MOUNTPOINT | grep Ventoy&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cp &lt;span style=&#34;color:#b8860b&#34;&gt;$disk_image&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;$MOUNTPOINT&lt;/span&gt;/guixdisk.img
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;eject &lt;span style=&#34;color:#b8860b&#34;&gt;$MOUNTPOINT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And then reboot to the Live CD environment and install the image.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dd /media/lubuntu/Ventoy/guixdisk.img &lt;span style=&#34;color:#b8860b&#34;&gt;of&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;/dev/sda &lt;span style=&#34;color:#b8860b&#34;&gt;status&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;progress
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;reboot
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;revitalising-guix&#34;&gt;Revitalising Guix&lt;/h2&gt;
&lt;p&gt;One-off shepherd services added to &lt;code&gt;operating-system&lt;/code&gt; earlier take care of
restoring &lt;code&gt;/storage&lt;/code&gt; from backup and activate the user home profile.
Check that everything worked as expected examining &lt;code&gt;/var/log/messages&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Wait guix-home-sarg to complete&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;until&lt;/span&gt; herd status guix-home-sarg | grep &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;It is stopped&amp;#39;&lt;/span&gt;; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;do&lt;/span&gt; &lt;span style=&#34;color:#a2f&#34;&gt;echo&lt;/span&gt; -n .; sleep 1; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;passwd root
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;passwd sarg
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;login sarg
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# app-specific restore commands&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;doom sync
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mu init -m ~/.mail
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mu index
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;logout&lt;/span&gt; &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# sarg&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;logout&lt;/span&gt; &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# root&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    

    <item>
      <title>wpa-manager.el and torrent-mode.el</title>
      <link>http://sarg.org.ru/blog/wifi-and-torrent/</link>
      <pubDate>Sun, 12 Mar 2023 00:00:00 +0100</pubDate>
      <author>sarg@sarg.org.ru (Sergey Trofimov)</author>
      <guid>http://sarg.org.ru/blog/wifi-and-torrent/</guid>
      <description>&lt;p&gt;There is a nice &lt;a href=&#34;https://elpa.gnu.org/packages/bluetooth.html&#34;&gt;bluetooth-mode&lt;/a&gt; to scan and connect to bluetooth devices, but no
such mode for wifi. It&amp;rsquo;s time to fix that. I&amp;rsquo;ve started implementing &lt;a href=&#34;https://github.com/sarg/wpa-manager.el&#34;&gt;wpa-manager&lt;/a&gt;
which controls &lt;a href=&#34;https://w1.fi/wpa_supplicant/&#34;&gt;wpa_supplicant&lt;/a&gt; over its D-Bus interface. Currently the manager
supports scanning and connecting using WPA PSK. It already solves most of my
use cases.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SSID                     BSSID                            Freq  Signal▼
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SARG                     5B:32:C6:8F:55:03                5180   -47
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;FRITZ!Box 7362 SL        7D:3D:12:D4:C1:1C                2417   -53
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ZYXEL-795                65:18:77:8E:6B:0C                2412   -56
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;WLAN-123488              27:49:1B:71:5D:F7                2412   -62
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;FRITZ!Box 7530 IG        F0:B4:4A:AB:B4:9F                2462   -63
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;WLAN-WWAAAB              83:F9:C3:23:C1:1C                2462   -65
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;FRITZ!Box 7430 DR        63:E7:BC:09:16:C0                2462   -73
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;WLAN-123488              B2:8A:27:3B:C7:39                5500   -75
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Another package is &lt;a href=&#34;https://github.com/sarg/torrent-mode.el&#34;&gt;torrent-mode&lt;/a&gt; which provides a tabulated view of a torrent
file content. An example of how it looks like.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   Idx ▼Size     Name
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   000  2.1k     dumpruninfo.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   001  4.8G     enwiki-20170220-abstract.xml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   002  741M     enwiki-20170220-abstract1.xml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   003  353M     enwiki-20170220-abstract2.xml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   004  259M     enwiki-20170220-abstract3.xml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   005  202M     enwiki-20170220-abstract4.xml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;*  006  168M     enwiki-20170220-abstract5.xml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;*  007  161M     enwiki-20170220-abstract6.xml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;*  008  183M     enwiki-20170220-abstract7.xml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;*  009  161M     enwiki-20170220-abstract8.xml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;*  010  133M     enwiki-20170220-abstract9.xml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This mode supports selecting individual files which could then be fed into &lt;a href=&#34;https://github.com/ukaszg/aria2&#34;&gt;aria2&lt;/a&gt;
using a small defun:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#a2f&#34;&gt;defun&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;torrent-mode-download-selected&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;dest-dir&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Download ARG entries.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#a2f&#34;&gt;interactive&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   (&lt;span style=&#34;color:#00a000&#34;&gt;list&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;read-directory-name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Directory: &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#a2f&#34;&gt;or&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;dired-dwim-target-directory&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#b8860b&#34;&gt;aria2-download-directory&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#800&#34;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#800&#34;&gt;t&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#b8860b&#34;&gt;torrent-mode&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;; aria2.addTorrent([secret, ]torrent[, uris[, options[, position]]])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#b8860b&#34;&gt;make-request&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#b8860b&#34;&gt;aria2--cc&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;aria2.addTorrent&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   (&lt;span style=&#34;color:#b8860b&#34;&gt;aria2--base64-encode-file&lt;/span&gt; &lt;span style=&#34;color:#00a000&#34;&gt;buffer-file-name&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#666&#34;&gt;`&lt;/span&gt;(&lt;span style=&#34;color:#a2f&#34;&gt;:select-file&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;,&lt;/span&gt;(&lt;span style=&#34;color:#b8860b&#34;&gt;string-join&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;seq-map&lt;/span&gt; (&lt;span style=&#34;color:#a2f&#34;&gt;lambda&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;el&lt;/span&gt;) (&lt;span style=&#34;color:#00a000&#34;&gt;number-to-string&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;car&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;el&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                         (&lt;span style=&#34;color:#b8860b&#34;&gt;tablist-get-marked-items&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;,&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#a2f&#34;&gt;:dir&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;,&lt;/span&gt;(&lt;span style=&#34;color:#00a000&#34;&gt;expand-file-name&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;dest-dir&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    

    <item>
      <title>Making org-mode movie diary</title>
      <link>http://sarg.org.ru/blog/org-watchlist/</link>
      <pubDate>Sun, 05 Mar 2023 00:00:00 +0100</pubDate>
      <author>sarg@sarg.org.ru (Sergey Trofimov)</author>
      <guid>http://sarg.org.ru/blog/org-watchlist/</guid>
      <description>&lt;p&gt;End result is here: &lt;a href=&#34;http://sarg.org.ru/movies/&#34;&gt;Movies&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;putting-it-in-org-mode&#34;&gt;Putting it in org-mode&lt;/h2&gt;
&lt;p&gt;Small demo of my flow:&lt;/p&gt;
&lt;p&gt;&lt;video controls&gt;&lt;source src=&#34;http://sarg.org.ru/media/demo-org-movies.mp4&#34; type=&#34;video/mp4&#34;&gt;
Your browser does not support the video tag.&lt;/video&gt;&lt;/p&gt;
&lt;p&gt;File organisation:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;#+STARTUP&lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;: logdrawer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;#+TODO&lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;: TODO(t) NEXT(n) | DONE(d!) DROPPED(c@)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#b68&#34;&gt; DONE&lt;/span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt; La Jetée (1962) :romance:scifi:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;:PROPERTIES:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;:rating: 4
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;:imdb: tt0056119
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;:END:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;:LOGBOOK:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;- State &amp;#34;DONE&amp;#34;       from              [2022-07-11 Mon]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;:END:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt; Watch List [0/1]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#800080;font-weight:bold&#34;&gt;**&lt;/span&gt;&lt;span style=&#34;&#34;&gt; TODO&lt;/span&gt; Big Buck Bunny (2008) :animation:short:comedy:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;:PROPERTIES:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;:imdb:     tt1254207
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;:END:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And here is a minor mode to automate inserting new entries.&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;code-snippet--api&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#a2f&#34;&gt;define-minor-mode&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;org-movies-mode&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Helper functions for movies.org&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a2f&#34;&gt;:keymap&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;list&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           (&lt;span style=&#34;color:#00a000&#34;&gt;cons&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;kbd&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;C-c C-i&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#00a000&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;org-movies-template&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           (&lt;span style=&#34;color:#00a000&#34;&gt;cons&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;kbd&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;C-c C-o&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#00a000&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;org-movies-open-letterboxd&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#a2f&#34;&gt;defun&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;org-movies-open-letterboxd&lt;/span&gt; ()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Open letterboxd for current entry.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#a2f&#34;&gt;interactive&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;&amp;#39;org-movies-mode&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#b8860b&#34;&gt;browse-url&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;format&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;https://letterboxd.com/imdb/%s&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                      (&lt;span style=&#34;color:#b8860b&#34;&gt;cdar&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;org-entry-properties&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;imdb&amp;#34;&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#a2f&#34;&gt;defun&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;org-movies-template&lt;/span&gt; ()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Convert imdb url at point to a diary entry.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#a2f&#34;&gt;interactive&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;&amp;#39;org-movies-mode&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#a2f&#34;&gt;let*&lt;/span&gt; ((&lt;span style=&#34;color:#b8860b&#34;&gt;ctx&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;org-element-context&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#b8860b&#34;&gt;link&lt;/span&gt; (&lt;span style=&#34;color:#a2f&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;eq&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;car&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;ctx&lt;/span&gt;) &lt;span style=&#34;color:#b8860b&#34;&gt;&amp;#39;link&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   (&lt;span style=&#34;color:#00a000&#34;&gt;plist-get&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;cadr&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;ctx&lt;/span&gt;) &lt;span style=&#34;color:#a2f&#34;&gt;:raw-link&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                 (&lt;span style=&#34;color:#d2413a;font-weight:bold&#34;&gt;error&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Not an org link&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#b8860b&#34;&gt;imdb&lt;/span&gt; (&lt;span style=&#34;color:#a2f&#34;&gt;or&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;nth&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;1&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;s-match&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                           (&lt;span style=&#34;color:#a2f&#34;&gt;rx&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;imdb.com/title/&amp;#34;&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;group&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;tt&amp;#34;&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;digit&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                           &lt;span style=&#34;color:#b8860b&#34;&gt;link&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   (&lt;span style=&#34;color:#d2413a;font-weight:bold&#34;&gt;error&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Not an imdb link&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#b8860b&#34;&gt;apikey&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;auth-source-pass-get&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;&amp;#39;secret&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Sites/omdbapi.com&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#b8860b&#34;&gt;movie&lt;/span&gt; (&lt;span style=&#34;color:#a2f&#34;&gt;with-current-buffer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    (&lt;span style=&#34;color:#b8860b&#34;&gt;url-retrieve-synchronously&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                     (&lt;span style=&#34;color:#00a000&#34;&gt;concat&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;http://omdbapi.com/?apikey=&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;apikey&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&amp;amp;i=&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;imdb&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  (&lt;span style=&#34;color:#00a000&#34;&gt;goto-char&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;url-http-end-of-headers&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  (&lt;span style=&#34;color:#b8860b&#34;&gt;json-read-from-string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   (&lt;span style=&#34;color:#00a000&#34;&gt;decode-coding-string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    (&lt;span style=&#34;color:#00a000&#34;&gt;buffer-substring&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;point&lt;/span&gt;) (&lt;span style=&#34;color:#00a000&#34;&gt;point-max&lt;/span&gt;)) &lt;span style=&#34;color:#b8860b&#34;&gt;&amp;#39;utf-8&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#b8860b&#34;&gt;genres-str&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;alist-get&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Genre&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;movie&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#00a000&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;string=&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#b8860b&#34;&gt;genres&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;-map&lt;/span&gt; (&lt;span style=&#34;color:#a2f&#34;&gt;lambda&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;el&lt;/span&gt;) (&lt;span style=&#34;color:#00a000&#34;&gt;downcase&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;s-replace&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;-&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;el&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                       (&lt;span style=&#34;color:#b8860b&#34;&gt;string-split&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;genres-str&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;, &amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#b8860b&#34;&gt;title&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;alist-get&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Title&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;movie&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#00a000&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;string=&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#b8860b&#34;&gt;year&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;alist-get&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Year&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;movie&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#800&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#00a000&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;string=&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#a2f&#34;&gt;pcase&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;org-element-type&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;org-element-at-point&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#b8860b&#34;&gt;&amp;#39;headline&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;ignore&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#b8860b&#34;&gt;_&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;beginning-of-line&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#b8860b&#34;&gt;kill-line&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#b8860b&#34;&gt;org-insert-heading&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#b8860b&#34;&gt;org-edit-headline&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;concat&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;title&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34; (&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;year&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;)&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#b8860b&#34;&gt;org-set-tags&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;genres&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#b8860b&#34;&gt;org-todo&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;TODO&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#b8860b&#34;&gt;org-set-property&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;imdb&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;imdb&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#b8860b&#34;&gt;org-movies-mode&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;&lt;a href=&#34;#code-snippet--api&#34;&gt;Code Snippet 1&lt;/a&gt;:&lt;/span&gt;
  Minor mode with useful helpers
&lt;/div&gt;
&lt;!--more--&gt;
&lt;h2 id=&#34;letterboxd-export&#34;&gt;Letterboxd export&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve fallen into this trap again&amp;hellip; I&amp;rsquo;ve relied on a 3rd party website to manage
my data. Yes, it looks good and it&amp;rsquo;s UX friendly, it&amp;rsquo;s easy to fall prey. This
time it was &lt;a href=&#34;https://letterboxd.com&#34;&gt;Letterboxd&lt;/a&gt;. I imported my &lt;a href=&#34;https://themoviedb.org&#34;&gt;TheMovieDB&lt;/a&gt; watchlist there and used it as
a film diary for a couple of years. One day I finally found some time to sort my
movie collection with &lt;a href=&#34;https://www.tinymediamanager.org&#34;&gt;tinyMediaManager&lt;/a&gt; and the icing on the cake was to add my
ratings to the NFO files. To my disappointment, Letterboxd doesn&amp;rsquo;t include the
imdb id in the export files, so I had to write a script to fetch all their short
urls one by one and extract the imdb ids from the html.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;re&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;requests&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;fileinput&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# takes file with https://boxd.it/71O short links&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;for&lt;/span&gt; row &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;in&lt;/span&gt; fileinput&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;input():
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    row &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; row&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;strip()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    d &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; requests&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;get(row)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    imdb &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; re&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;findall(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;(?&amp;lt;=imdb.com/title/)tt[^/]+&amp;#39;&lt;/span&gt;, d&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;text)[&lt;span style=&#34;color:#666&#34;&gt;0&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a2f&#34;&gt;print&lt;/span&gt;(row, imdb, sep&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;,&amp;#39;&lt;/span&gt;, flush&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;importing-ratings-in-nfo-files&#34;&gt;Importing ratings in NFO files&lt;/h2&gt;
&lt;p&gt;Then another script to put the ratings in the NFO files.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;re&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;sys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;csv&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;glob&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;r &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; csv&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;reader(&lt;span style=&#34;color:#a2f&#34;&gt;open&lt;/span&gt;(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;/home/sarg/rated.csv&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rates &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;for&lt;/span&gt; n &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;in&lt;/span&gt; glob&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;glob(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;/media/sarg/2TB/Movies/**/**/*.nfo&amp;#39;&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    imdb &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; re&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;findall(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;(?&amp;lt;=&amp;lt;id&amp;gt;)tt\d+&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#a2f&#34;&gt;open&lt;/span&gt;(n)&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;read())[&lt;span style=&#34;color:#666&#34;&gt;0&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt; imdb &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;in&lt;/span&gt; rates:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        rates&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;pop(imdb)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        d &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; re&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;sub(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;&amp;lt;userrating&amp;gt;0.0&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;&amp;lt;userrating&amp;gt;&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a2f&#34;&gt;str&lt;/span&gt;(rates[imdb]), d)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        f &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a2f&#34;&gt;open&lt;/span&gt;(n &lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;.new&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;w&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        f&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;write(d)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        f&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;close()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;print&lt;/span&gt;(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;High rated movies I don&amp;#39;t have:&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;for&lt;/span&gt; imdb &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;in&lt;/span&gt; rates:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt; rates[imdb]&lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;7&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a2f&#34;&gt;print&lt;/span&gt;(&lt;span style=&#34;color:#b44&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;https://imdb.com/title/&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;{&lt;/span&gt;imdb&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    

    <item>
      <title>Exporting Liked Videos from Youtube</title>
      <link>http://sarg.org.ru/blog/export-youtube-liked/</link>
      <pubDate>Sun, 26 Feb 2023 00:00:00 +0100</pubDate>
      <author>sarg@sarg.org.ru (Sergey Trofimov)</author>
      <guid>http://sarg.org.ru/blog/export-youtube-liked/</guid>
      <description>&lt;p&gt;Over the years I&amp;rsquo;ve collected ~300 favourite videos and unfortunately some of
them have been taken down. I have spent some time re-watching the old videos and
still enjoy them. Few are just for laughs, some are educational and others are
just art. As there are not too many of them, I can just download them all to my
archives. 14 videos that were missing on Youtube I&amp;rsquo;ve recovered from
&lt;a href=&#34;https://web.archive.org&#34;&gt;https://web.archive.org&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The resulting archive weighs in at just 13G, so it really is a no-brainer to keep it offline.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# https://gist.github.com/guidocella/a272b6e68f9c44532b011f6596e95c61&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a2f&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;# Netscape HTTP Cookie File&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# needed by youtube-dl&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#b8860b&#34;&gt;QUERY&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;SELECT
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;            host_key,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;            IIF(host_key LIKE &amp;#39;.%&amp;#39;, &amp;#39;TRUE&amp;#39;, &amp;#39;FALSE&amp;#39;),
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;            path,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;            IIF(is_secure, &amp;#39;TRUE&amp;#39;, &amp;#39;FALSE&amp;#39;),
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;            IIF(expires_utc == 0, 0, expires_utc / 1000000 - 11644473600),
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;            name,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;            value
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;        FROM cookies;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# There is no attempt to url encode $1, but SQLite already handles&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# characters like spaces, so only ? % and # should cause issues.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    sqlite3 -readonly -separator &lt;span style=&#34;color:#b44&#34;&gt;$&amp;#39;\t&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;file:&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;:-&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$HOME&lt;/span&gt;/.local/share/qutebrowser&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;/webengine/Cookies?nolock=1&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$QUERY&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;}&lt;/span&gt; &amp;gt; cookies.txt
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;Code Snippet 1:&lt;/span&gt;
  Export &lt;code&gt;qutebrowser&lt;/code&gt; cookies for &lt;code&gt;yt-dlp&lt;/code&gt;
&lt;/div&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;yt-dlp --ignore-errors &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    --download-archive archive.txt &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    --cookies cookies.txt &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;https://www.youtube.com/playlist?list=LL&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;src-block-caption&#34;&gt;
  &lt;span class=&#34;src-block-number&#34;&gt;Code Snippet 2:&lt;/span&gt;
  Download everything from the Liked Videos playlist
&lt;/div&gt;
</description>
    </item>
    

    <item>
      <title>📖 Cracking The Code To A Successful Interview</title>
      <link>http://sarg.org.ru/blog/cracking-interview/</link>
      <pubDate>Thu, 28 May 2020 00:00:00 +0200</pubDate>
      <author>sarg@sarg.org.ru (Sergey Trofimov)</author>
      <guid>http://sarg.org.ru/blog/cracking-interview/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://www.goodreads.com/book/show/32794226-cracking-the-code-to-a-successful-interview&#34;&gt;Goodreads&lt;/a&gt; - 3/5.&lt;/p&gt;
&lt;p&gt;First impression:
Overall the tone of the book is slightly arrogant. The author&amp;rsquo;s ego is soaking from every page.&lt;/p&gt;
&lt;p&gt;After the read:
The book is best suited for a sales position in corporate America.
Overall the message of the book is: &lt;strong&gt;Be prepared, know what&amp;rsquo;s expected of you and give it to the inverviewer in advance.&lt;/strong&gt;
In chapter 9 there is a summary of REAPRICH method. Chapter 10-12,15 are unrelated to hiring process.&lt;/p&gt;
&lt;h2 id=&#34;chapter-1-dot&#34;&gt;Chapter 1.&lt;/h2&gt;
&lt;p&gt;Hiring managers could be of 4 types:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the power tripper - tries to prove his own intellectual prowess&lt;/li&gt;
&lt;li&gt;the defensive crouhcer - feels unsafe with poeple they fear could do their jobs better&lt;/li&gt;
&lt;li&gt;method man - follows script and expects valid answers&lt;/li&gt;
&lt;li&gt;rogue agent - not fitting in 3 types above, dark horse&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;REAPRICH - 8 step plan to win the interview.
results / energy / attitude / process / relationships / interview the  interviewer / close the interviewer / humanity&lt;/p&gt;
&lt;h2 id=&#34;chapter-2&#34;&gt;Chapter 2&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;research the company&lt;/li&gt;
&lt;li&gt;polish resume&lt;/li&gt;
&lt;li&gt;be tenacious&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On the day of interview - be on time, dress well, shine your shoes, bring hard copy of your resume, give a firm handshake, look into the eye.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t discuss personal problems, family, bad experiences with past employers.&lt;/p&gt;
&lt;h2 id=&#34;chapter-3-dot-rea&#34;&gt;Chapter 3. REA&lt;/h2&gt;
&lt;p&gt;Be enthusiastic (E - energy) and have positive A (attitude).&lt;/p&gt;
&lt;h2 id=&#34;chapter-4-dot-p-spotlight-on-creativity&#34;&gt;Chapter 4. P - Spotlight on creativity&lt;/h2&gt;
&lt;p&gt;You’re in great shape if the manager ends up saying, “I want you on board so you can do this for me or my team. I want this to be a part of our skill set and our arsenal as we move forward as an organization.”&lt;/p&gt;
&lt;h2 id=&#34;chapter-5-dot-r-relationships&#34;&gt;Chapter 5. R - Relationships&lt;/h2&gt;
&lt;p&gt;One of the biggest fears of hiring managers is having a personality conflict on their team. Showing that you have the ability to create and maintain relationships alleviates this fear.&lt;/p&gt;
&lt;p&gt;Exercise:
Write down two long-term relationships such as bosses, coaches, mentors, or friends (one which affected your career). Answer the following questions in writing for each: How did you secure this relationship? Was it through performance? How did this person become interested in you? How did he or she see positive qualities in you? How did you build and nurture this connection?&lt;/p&gt;
&lt;h2 id=&#34;chapter-6-dot-i-interview-the-interviewer&#34;&gt;Chapter 6. I - interview the interviewer&lt;/h2&gt;
&lt;p&gt;Ask something that you can&amp;rsquo;t find in public sources.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tell me about some of your most successful people. What’s made them great?&lt;/li&gt;
&lt;li&gt;How can I help your team? What is the best way my skills could add value?&lt;/li&gt;
&lt;li&gt;If you hired me today, what would you have me help you and your team with in the first three months?&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;chapter-7-dot-close-the-interview&#34;&gt;Chapter 7. Close the interview&lt;/h2&gt;
&lt;p&gt;Like in sales - try to close the deal.&lt;/p&gt;
&lt;h2 id=&#34;chapter-8-dot-humanity&#34;&gt;Chapter 8. Humanity&lt;/h2&gt;
&lt;p&gt;Small talk in the end. Author suggests to directly ask if you&amp;rsquo;re recommended for hire.&lt;/p&gt;
&lt;h2 id=&#34;chapter-9-dot-recap-dot&#34;&gt;Chapter 9. Recap.&lt;/h2&gt;
&lt;p&gt;The most successful interview candidates aren’t necessarily the most experienced, the most educated, or the most qualified for the job. They are the best prepared.&lt;/p&gt;
&lt;h2 id=&#34;chapter-14-dot-tough-questions&#34;&gt;Chapter 14. Tough questions&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Who are you?&lt;/li&gt;
&lt;li&gt;Why should I hire you?&lt;/li&gt;
&lt;li&gt;Give an example of a time you tried your best and failed.&lt;/li&gt;
&lt;li&gt;Who was the worst boss (or employee) you ever worked with?&lt;/li&gt;
&lt;li&gt;What four words would someone close to you use to describe you?&lt;/li&gt;
&lt;li&gt;Who was your best mentor?&lt;/li&gt;
&lt;li&gt;What do you feel you will bring to this organization?&lt;/li&gt;
&lt;li&gt;Where do you want to be in five years?&lt;/li&gt;
&lt;li&gt;What is your greatest weakness?&lt;/li&gt;
&lt;li&gt;What is your ninety-day plan to be successful here?&lt;/li&gt;
&lt;li&gt;Give me an example of where you took a difficult customer or situation and turned it into a win.&lt;/li&gt;
&lt;/ol&gt;
</description>
    </item>
    

    <item>
      <title>📖 Growing Object-Oriented Softwared, Guided by Tests.</title>
      <link>http://sarg.org.ru/blog/tdd-freeman/</link>
      <pubDate>Tue, 19 May 2020 00:00:00 +0200</pubDate>
      <author>sarg@sarg.org.ru (Sergey Trofimov)</author>
      <guid>http://sarg.org.ru/blog/tdd-freeman/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve finished reading &lt;a href=&#34;https://www.goodreads.com/book/show/4268826-growing-object-oriented-software-guided-by-tests&#34;&gt;Growing Object-Oriented Softwared, Guided by Tests&lt;/a&gt; by
Steve Freeman and Nat Pryce. The book is a good introduction into TDD. First it
goes through core concepts and then demonstrates how to implement TDD on a simple project.&lt;/p&gt;
&lt;p&gt;My takeouts throughout the reading:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TDD is a core practice of XP. TDD is not about keeping defects from the users, but helping the team to understand the features and to deliver them reliably and predictably.&lt;/li&gt;
&lt;li&gt;Making code accessible for testing often drives it towards being cleaner and more modular.&lt;/li&gt;
&lt;li&gt;TDD cycle: red/green/refactor&lt;/li&gt;
&lt;li&gt;Different kinds of tests:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;acceptance&lt;/strong&gt; - exercises the functionality we want to build. Does the whole system work? Whenever possible should be end-to-end without directly calling internal code.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;integration&lt;/strong&gt; - does our code work against code we can&amp;rsquo;t change?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;unit&lt;/strong&gt; - do our objects do the right thing, are they convenient to work with?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;External/internal quality: customer facing or developer/admin facing&lt;/li&gt;
&lt;li&gt;OOP focuses more on the communication between objects than on the objects themselves. An object has a method of handling every type of message that it understands and in encapsulates some internal state.&lt;/li&gt;
&lt;li&gt;Objects could have different semantics:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;values&lt;/strong&gt; model unchanging quantities&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;objects&lt;/strong&gt; have identity that may change over time and model computational process&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;TDD best practices:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First make a minimal &amp;ldquo;skeleton&amp;rdquo; of an app and set up deployment infrastructure. E.g. for a web app it would be a one page site which shows a field in database.&lt;/li&gt;
&lt;li&gt;Develop from outer boundary. E.g. write end-to-end acceptance test and start unrolling the logic from the incoming external message.&lt;/li&gt;
&lt;li&gt;The development cycle goes like this. When implementing an object, we discover that it needs a service to be provided by another object. We give the new service a name and mock it out in the client object’s unit tests, to clarify the relationship between the two. Then we write an object to provide that service and, in doing so, discover what services that object needs. We follow this chain (or perhaps a directed graph) of collaborator relationships until we connect up to existing objects, either our own or from a third-party API. We think of this as “on-demand” design: we “pull” interfaces and their implementations into existence from the needs of the client, rather than “pushing” out the features that we think a class should provide.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    

    <item>
      <title>Exporting watch list from TMDb</title>
      <link>http://sarg.org.ru/blog/tmdb-export/</link>
      <pubDate>Sun, 26 Apr 2020 00:00:00 +0200</pubDate>
      <author>sarg@sarg.org.ru (Sergey Trofimov)</author>
      <guid>http://sarg.org.ru/blog/tmdb-export/</guid>
      <description>&lt;p&gt;I keep list of movies I&amp;rsquo;ve watched on &lt;a href=&#34;https://www.themoviedb.org/u/sarg/ratings&#34;&gt;TheMovieDB&lt;/a&gt;. The service is great and I&amp;rsquo;ve
used it for quite a long time (&amp;gt;700 movies in my list). I was using another
service before, which unfortunately had closed without giving me a chance to
export the data and I had to scrape my watchlist from the google cache.&lt;/p&gt;
&lt;p&gt;To prevent that from happening again, I&amp;rsquo;ve exported my watchlist from TMDb and
will use the service only as a secondary source with a nice UI.&lt;/p&gt;
&lt;p&gt;TMDb has a decent API and there are several python wrappers for it. The script
for export is pretty straightforward. Retrieve &lt;code&gt;request_token&lt;/code&gt;, open a session
(login) for your account and retrieve the list of rated movies from a paginated
endpoint.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;tmdbsimple&lt;/span&gt; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;tmdb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;json&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;subprocess&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tmdb&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;API_KEY &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;bafca4e813ca8fc43b3c9f1e32d1932b&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;res &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; subprocess&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;run(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    [&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;pass&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;show&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Sites/themoviedb.org&amp;#34;&lt;/span&gt;], capture_output&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;True&lt;/span&gt;, check&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;True&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;password &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; res&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;stdout&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;splitlines()[&lt;span style=&#34;color:#666&#34;&gt;0&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;auth &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; tmdb&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Authentication()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;token &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; auth&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;token_new()[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;request_token&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;auth&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;token_validate_with_login(request_token&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;token, username&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;sarg&amp;#34;&lt;/span&gt;, password&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;password)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;session_id &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; auth&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;session_new(request_token&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;token)[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;session_id&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;acc &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; tmdb&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Account(session_id)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;acc&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;info()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;movies &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;idx &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;while&lt;/span&gt; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;True&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    res &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; acc&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;rated_movies(page&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;idx)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    movies &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; movies &lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt; res[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;results&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    idx &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; idx &lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt; idx &lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&lt;/span&gt; res[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;total_pages&amp;#34;&lt;/span&gt;]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;idx &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;while&lt;/span&gt; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;True&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    res &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; acc&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;watchlist_movies(page&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;idx)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    movies &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; movies &lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt; res[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;results&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    idx &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; idx &lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt; idx &lt;span style=&#34;color:#666&#34;&gt;&amp;gt;&lt;/span&gt; res[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;total_pages&amp;#34;&lt;/span&gt;]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;print&lt;/span&gt;(json&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;dumps(movies, indent&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;2&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Unfortunately TMDb does not expose &lt;code&gt;Rated Date&lt;/code&gt; via API. It could be extracted
from the CSV export though. Request the CSV export on the &amp;ldquo;My Ratings&amp;rdquo;
page (under three dots icon). It would be sent by email. Download the file and
use the following script to merge the json and csv.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;csv&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;json&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rates &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; { row[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;TMDb ID&amp;#34;&lt;/span&gt;]: row &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;for&lt;/span&gt; row &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;in&lt;/span&gt; csv&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;DictReader(&lt;span style=&#34;color:#a2f&#34;&gt;open&lt;/span&gt;(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;ratings.csv&amp;#34;&lt;/span&gt;)) }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;films &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; json&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;load(&lt;span style=&#34;color:#a2f&#34;&gt;open&lt;/span&gt;(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;movies.json&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;for&lt;/span&gt; film &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;in&lt;/span&gt; films:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#a2f&#34;&gt;str&lt;/span&gt;(film[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;id&amp;#39;&lt;/span&gt;]) &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;in&lt;/span&gt; rates:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        film[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;rated_date&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; rates[&lt;span style=&#34;color:#a2f&#34;&gt;str&lt;/span&gt;(film[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;id&amp;#39;&lt;/span&gt;])][&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;Date Rated&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;print&lt;/span&gt;(json&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;dumps(films, indent&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;2&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    

    <item>
      <title>Android apps that I use</title>
      <link>http://sarg.org.ru/blog/android-apps/</link>
      <pubDate>Fri, 24 Apr 2020 00:00:00 +0200</pubDate>
      <author>sarg@sarg.org.ru (Sergey Trofimov)</author>
      <guid>http://sarg.org.ru/blog/android-apps/</guid>
      <description>&lt;p&gt;My phone is running &lt;a href=&#34;https://github.com/phhusson/treble_experimentations&#34;&gt;AOSP&lt;/a&gt; without google services and almost all of the
applications I use come from &lt;a href=&#34;https://f-droid.org&#34;&gt;F-Droid&lt;/a&gt;. Few exceptions are the apps for paid
services that I use and they are installed from Aurora Store.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I use &lt;a href=&#34;https://github.com/mvdan/fdroidcl&#34;&gt;fdroidcl&lt;/a&gt; to install and update applications.&lt;/li&gt;
&lt;li&gt;Backup is covered in the post &amp;ldquo;&lt;a href=&#34;http://sarg.org.ru/blog/android-backup/&#34;&gt;Backing up an Android phone&lt;/a&gt;&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;I use syncthing to share a directory between my laptops and the phone.&lt;/li&gt;
&lt;li&gt;I have &amp;ldquo;Password Store&amp;rdquo; files in the shared directory in case I need access to
passwords on the phone (rarely).&lt;/li&gt;
&lt;li&gt;In AFWall+ I whitelist only selected apps. All others are denied to access the net.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;f-droid-apps&#34;&gt;F-Droid apps&lt;/h2&gt;
&lt;p&gt;&lt;a id=&#34;table--fdroid-apps&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Name&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;&lt;a href=&#34;https://f-droid.org/packages/com.ichi2.anki&#34;&gt;AnkiDroid&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;A flashcard-based study aid&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/de.danoeh.antennapod&#34;&gt;AntennaPod&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Easy-to-use, flexible and open-source podcast manager and player&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/com.aurora.store&#34;&gt;Aurora Store&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Play store alternative&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/de.markusfisch.android.binaryeye&#34;&gt;BinaryEye&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Yet another barcode scanner for Android. Free, no ads and open source.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/org.solovyev.android.calculator&#34;&gt;Calculator++&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Scientific calculator with sleek interface and powerful capabilities&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/org.mozilla.fennec_fdroid&#34;&gt;Fennec F-Droid&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Browse the web&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/com.apps.adrcotfas.goodtime&#34;&gt;Goodtime&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Minimalist Pomodoro Timer&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/com.fsck.k9&#34;&gt;K-9 Mail&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Full-featured email client&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/de.mm20.launcher2.release&#34;&gt;Kvaesitso&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;A search-focused, free and open source launcher for Android&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/org.koreader.launcher.fdroid&#34;&gt;KOReader&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Ebook reader supporting multiple formats like PDF, DjVu, EPUB, FB2&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/org.linphone&#34;&gt;LinPhone&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;SIP (VOIP) phone&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/org.secuso.privacyfriendlymemory&#34;&gt;Memo Game&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Find pairs of cards&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/com.artifex.mupdf.viewer.app&#34;&gt;MuPDF viewer&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Lightweight document viewer&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/org.polymorphicshade.newpipe&#34;&gt;NewPipe x SponsorBlock&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;A free lightweight YouTube frontend for Android with SponsorBlock capabilities&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/de.schildbach.oeffi&#34;&gt;Offi Stations&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;King of public transit planning!&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/org.sufficientlysecure.keychain&#34;&gt;OpenKeychain&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Encrypt your Files and Communications. Compatible with the OpenPGP Standard.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/de.blinkt.openvpn&#34;&gt;OpenVPN for Android&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;OpenVPN without root&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/com.orgzlyrevived&#34;&gt;Orgzly Revived&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Outliner for taking notes and managing to-do lists in Org-mode format&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/net.osmand.plus&#34;&gt;OsmAnd~&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Global Mobile Map Viewing &amp;amp; Navigation for Offline and Online OSM Maps&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/org.ligi.passandroid&#34;&gt;PassAndroid&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;View Passbook files&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/dev.msfjarvis.aps&#34;&gt;Password Store&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Manage your passwords&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/org.olgsoft.apipepanic&#34;&gt;PipePanic&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;A plumbers favorite game&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/name.boyle.chris.sgtpuzzles&#34;&gt;Puzzles&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;39 single-player logic games&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/com.moez.QKSMS&#34;&gt;QKSMS&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Messaging app&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/de.reimardoeffinger.quickdic&#34;&gt;QuickDic&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Offline translation dictionary&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/xyz.deepdaikon.quinb&#34;&gt;Quinb&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;A multiplayer reaction game: train your mind and your reflexes while having fun.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/com.vonglasow.michael.satstat&#34;&gt;SatStat&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;GPS, sensor and network status&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/org.galexander.sshd&#34;&gt;SimpleSSHD&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Easy to use SSH server&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/com.nutomic.syncthingandroid&#34;&gt;Syncthing&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;File synchronization&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/org.telegram.messenger&#34;&gt;Telegram&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Telegram is a messaging app with a focus on speed and security.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/org.videolan.vlc&#34;&gt;VLC&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;The best video and music player. Fast and “just works”, plays any file&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/de.ph1b.audiobook&#34;&gt;Voice&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Simple audiobook player&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;archive&#34;&gt;Archive&lt;/h2&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Name&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;&lt;a href=&#34;https://f-droid.org/packages/fr.neamar.kiss&#34;&gt;KISS launcher&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Custom launcher&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/dev.ukanth.ufirewall&#34;&gt;AFWall+&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Control network traffic&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/com.menny.android.anysoftkeyboard&#34;&gt;AnySoftKeyboard&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Keyboard&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/com.amaze.filemanager&#34;&gt;Amaze&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Manage local files&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/org.shadowice.flocke.andotp&#34;&gt;andOTP&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Time-based One-time Passwords (TOTP) from QR codes for two-factor authentication&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/com.simplemobiletools.clock&#34;&gt;Clock&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;A combination of a clock, alarm, stopwatch and timer.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/org.isoron.uhabits&#34;&gt;Loop Habit Tracker&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Track your habits and long-term goals&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/com.github.axet.binauralbeats&#34;&gt;Binaural Beats&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Meditation helper&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/org.ligi.survivalmanual&#34;&gt;Survival Manual&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Learn how to survive&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/de.meonwax.soundboard&#34;&gt;Soundboard&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Play short sound samples on touch&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/com.jmstudios.redmoon&#34;&gt;Red Moon&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Filter blue light from your screen for a better sleep&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/com.mendhak.gpslogger&#34;&gt;GPSLogger&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Lightweight GPS Logging&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/com.spitslide.derdiedas&#34;&gt;Der Die Das&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;learning genders of German nouns&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/net.sourceforge.opencamera&#34;&gt;Open Camera&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Camera App&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/com.google.android.gms&#34;&gt;UnifiedNlp (no GAPPS)&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Location provider middleware (UnifiedNlp)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/com.nicue.onetwo&#34;&gt;OneTwo&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Provides you with dices, counter and timers&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/sh.ftp.rocketninelabs.meditationassistant.opensource&#34;&gt;Meditation Assistant&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Feature packed meditation session timer and recorder&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/org.fitchfamily.android.gsmlocation&#34;&gt;LocalGsmNlpBackend&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;UnifiedNlp location provider (local GSM database)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/saschpe.poker&#34;&gt;Planning Poker&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Planning Poker for phone, tablet and wear devices&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/org.microg.nlp.backend.nominatim&#34;&gt;NominatimNlpBackend&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;UnifiedNlp geocoding provider (MapQuest Nominatim)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://f-droid.org/packages/org.openbmap&#34;&gt;RadioBeacon&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;Contribute to coverage maps&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
</description>
    </item>
    

    <item>
      <title>Backing up an Android phone</title>
      <link>http://sarg.org.ru/blog/android-backup/</link>
      <pubDate>Fri, 24 Apr 2020 00:00:00 +0200</pubDate>
      <author>sarg@sarg.org.ru (Sergey Trofimov)</author>
      <guid>http://sarg.org.ru/blog/android-backup/</guid>
      <description>&lt;p&gt;One day my wife asked me to help her backup about 30Gb of photos from her
android phone. At first we had tried to copy files over MTP (in Win10). This
idea quickly showed its incapacity. You see, Win10 wants to be nice and tries
to calculate ETA. But 30Gb is a lot of files and over MTP it takes one request
per file to get its size. So, we waited half an hour while Win10 was preparing
to start the transfer and I had aborted this madness.&lt;/p&gt;
&lt;p&gt;Here is a sane approach to do the job.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install &lt;a href=&#34;https://f-droid.org/packages/org.galexander.sshd/&#34;&gt;SimpleSSHD&lt;/a&gt; on the phone.
Set &lt;code&gt;&amp;quot;Start on Open&amp;quot;&lt;/code&gt; in app settings.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Grab &lt;a href=&#34;https://github.com/google/adb-sync#adb-channel&#34;&gt;&lt;code&gt;adb-channel&lt;/code&gt;&lt;/a&gt; script and add this snippet to &lt;code&gt;~/.ssh/config&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   Host sshelper
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       Port 2222
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       ProxyCommand adb-channel tcp:%p org.galexander.sshd/.SimpleSSHD 1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Copy your public key to the phone.&lt;/p&gt;
&lt;p&gt;Please note that &lt;code&gt;ssh-copy-id&lt;/code&gt; won&amp;rsquo;t work. Just &lt;code&gt;ssh sshelper&lt;/code&gt; and then paste
the key from &lt;code&gt;ssh-add -L&lt;/code&gt; into &lt;code&gt;authorized_keys&lt;/code&gt;. Details &lt;a href=&#34;http://www.galexander.org/software/simplesshd/&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now backup with rsync as usual.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   rsync -e ssh -av sshelper:/sdcard/DCIM .
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Optional&lt;/p&gt;
&lt;p&gt;This setup assumes that you copy files over USB. But nothing stops you from
starting SimpleSSHD manually and copy files over WiFi.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   rsync -e &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;ssh -p 2222&amp;#39;&lt;/span&gt; -av 192.168.178.42:/sdcard/DCIM .
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now that newer Android versions (newer than 12 I believe) don&amp;rsquo;t allow apps to
access files of other apps, I had to revisit my backup solution.&lt;/p&gt;
&lt;p&gt;Now I simply use the &lt;code&gt;adb-sync&lt;/code&gt; script, but I also do &lt;code&gt;adb root&lt;/code&gt; to give the
script full access to any files. The script is pretty smart and it works kind of
like rsync, downloading only newer files. It fits perfect the use case.&lt;/p&gt;
</description>
    </item>
    

    <item>
      <title>Making a hugo powered blog in emacs</title>
      <link>http://sarg.org.ru/blog/emacs-hugo/</link>
      <pubDate>Wed, 22 Apr 2020 00:00:00 +0200</pubDate>
      <author>sarg@sarg.org.ru (Sergey Trofimov)</author>
      <guid>http://sarg.org.ru/blog/emacs-hugo/</guid>
      <description>&lt;p&gt;Starting a blog this days couldn&amp;rsquo;t be easier. Ten simple steps to get started.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://help.github.com/en/github/working-with-github-pages/creating-a-github-pages-site&#34;&gt;Create a github pages repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Check it out locally, e.g. to &lt;code&gt;~/blog&lt;/code&gt;. Every file you put in the repo will
be published &lt;a href=&#34;https://help.github.com/en/github/working-with-github-pages/about-github-pages-and-jekyll#configuring-jekyll-in-your-github-pages-site&#34;&gt;automatically&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;By default, Jekyll doesn&amp;rsquo;t build files or folders that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;are located in a folder called &lt;code&gt;/node_modules&lt;/code&gt; or &lt;code&gt;/vendor&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;start with &lt;code&gt;_&lt;/code&gt;, &lt;code&gt;.&lt;/code&gt;, or &lt;code&gt;#&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;end with &lt;code&gt;~&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;are excluded by the exclude setting in your configuration file&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://help.github.com/en/github/working-with-github-pages/configuring-a-custom-domain-for-your-github-pages-site&#34;&gt;Configure&lt;/a&gt; custom domain or just use the default &lt;code&gt;&amp;lt;repo&amp;gt;.github.io&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create &lt;code&gt;~/blog/_hugo/config.toml&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    baseURL = &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;http://sarg.org.ru/&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    languageCode = &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;en-us&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    title = &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Random forest&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    theme = &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;anubis&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# see the next step&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    publishDir = &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;../&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# github pages look in the root folder by default&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Checkout some &lt;a href=&#34;https://themes.gohugo.io/&#34;&gt;theme&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    git submodule add   &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    https://github.com/Mitrichius/hugo-theme-anubis.git &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    _hugo/themes/anubis
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add &lt;code&gt;_hugo/content&lt;/code&gt; to &lt;code&gt;.gitignore&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This directory will be generated by &lt;code&gt;ox-hugo&lt;/code&gt;, no need to store it in git.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create &lt;code&gt;org-mode&lt;/code&gt; file where all the content would be placed.&lt;/p&gt;
&lt;p&gt;Use the &lt;a href=&#34;https://ox-hugo.scripter.co/#screenshot-one-post-per-subtree&#34;&gt;instruction&lt;/a&gt; from &lt;code&gt;ox-hugo&lt;/code&gt; documentation. But make sure that
&lt;code&gt;#+HUGO_BASE_DIR&lt;/code&gt; points to &lt;code&gt;_hugo&lt;/code&gt; directory. You can put the file whenever
you want, not strictly necessary in the repository.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Export the file with &lt;code&gt;ox-hugo&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Press &lt;code&gt;C-c C-e H A&lt;/code&gt; to export everything. Now &lt;code&gt;_hugo/content&lt;/code&gt; should be
populated. You might want to enable &lt;a href=&#34;https://ox-hugo.scripter.co/doc/auto-export-on-saving/&#34;&gt;auto export on saving&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Check that your blog works locally.&lt;/p&gt;
&lt;p&gt;Go to &lt;code&gt;_hugo/&lt;/code&gt; and run &lt;code&gt;hugo server -D&lt;/code&gt;. Hugo should start on &lt;a href=&#34;http://localhost:1313&#34;&gt;http://localhost:1313&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Generate html for github pages.&lt;/p&gt;
&lt;p&gt;Run &lt;code&gt;hugo&lt;/code&gt; and it&amp;rsquo;ll create all the files in &lt;code&gt;publishDir&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Commit and push all the changes. You&amp;rsquo;re done! 🎉&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    

    <item>
      <title>Advent of Code 2019</title>
      <link>http://sarg.org.ru/blog/aoc2019/</link>
      <pubDate>Wed, 01 Jan 2020 00:00:00 +0100</pubDate>
      <author>sarg@sarg.org.ru (Sergey Trofimov)</author>
      <guid>http://sarg.org.ru/blog/aoc2019/</guid>
      <description>&lt;p&gt;For the first time I&amp;rsquo;ve participated in &lt;a href=&#34;https://adventofcode.com/2019&#34;&gt;&amp;ldquo;Advent of Code&amp;rdquo;&lt;/a&gt; contest. It promised to
be a fun time and a good opportunity to learn a new programming language. I&amp;rsquo;ve
taken Clojure from my bucket list and dived head first into the contest.&lt;/p&gt;
&lt;p&gt;The first few tasks are deliberately very easy, so that participants firstly
would get into the mood and would not detract by the bar raised too high, and
secondly to let one to get acquainted with the platform and rules, set up the
coding environment and get hands-on with the new language (if you one uses
such).&lt;/p&gt;
&lt;p&gt;The problems were of varying complexity and some of them required prior
knowledge of algorithms. The hardest one were about searching a path in a maze.
The cool twist was the addition of the IntCode virtual machine. Over the course
of a few days the problems were shaping the definition of the IndCode VM.
Participants were expected to implement and to debug it in order to solve the
problem.&lt;/p&gt;
&lt;p&gt;Clojure has shown strong and I&amp;rsquo;ve rarely struggled with the language. Debugging
tools could be better though. All the solutions could be found &lt;a href=&#34;https://github.com/sarg/advent2019&#34;&gt;here on Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For an additional fun I&amp;rsquo;ve produced animations for some of the problems. For
that I&amp;rsquo;ve used awesome &lt;a href=&#34;https://github.com/quil/quil&#34;&gt;Quil&lt;/a&gt; library which implements &lt;a href=&#34;https://processing.org/reference&#34;&gt;Processing.org API&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;problem-13-care-package&#34;&gt;&lt;a href=&#34;https://adventofcode.com/2019/day/13&#34;&gt;Problem 13 - Care Package&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Arkanoid AI should be implemented in IntCode. Each block in the game has its own
unique value and the answer of the problem is the end score.&lt;/p&gt;
&lt;p&gt;&lt;video controls&gt;&lt;source src=&#34;https://raw.githubusercontent.com/sarg/advent2019/master/resources/day13.mp4&#34;&gt;&lt;/video&gt;&lt;/p&gt;
&lt;h2 id=&#34;problem-15-oxygen-system&#34;&gt;&lt;a href=&#34;https://adventofcode.com/2019/day/15&#34;&gt;Problem 15 - Oxygen System&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A robot have been deployed to a maze of unknown structure. By issuing movement
and observation commands the maze should be fully explored and a marked cell
should be found. Then the time to fill the maze with air should be calculated,
given that the air is injected in the bottome left corner and it spreads each
tick to the adjacent cells.&lt;/p&gt;
&lt;p&gt;&lt;video controls&gt;&lt;source src=&#34;https://raw.githubusercontent.com/sarg/advent2019/master/resources/day15.mp4&#34;&gt;&lt;/video&gt;&lt;/p&gt;
</description>
    </item>
    

    <item>
      <title>  &#34;Parental control&#34; for emacs
  </title>
      <link>http://sarg.org.ru/blog/telega-otp/</link>
      <pubDate>Fri, 21 Sep 2018 00:00:00 +0000</pubDate>
      <author>sarg@sarg.org.ru (Sergey Trofimov)</author>
      <guid>http://sarg.org.ru/blog/telega-otp/</guid>
      <description>&lt;p&gt;It easily becomes automatic to check for notifications/new messages/new emails
etc. To give my rational self some time to intercept compulsive behaviour I have
made this elisp snippet.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#a2f&#34;&gt;defun&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;sarg/otp-for-confirm&lt;/span&gt; ()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Generates random hex string&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#00a000&#34;&gt;format&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;%06x%06x%06x&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#00a000&#34;&gt;random&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;expt&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;16&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;6&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#00a000&#34;&gt;random&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;expt&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;16&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;6&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          (&lt;span style=&#34;color:#00a000&#34;&gt;random&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;expt&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;16&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;6&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#a2f&#34;&gt;defun&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;confirm-advice&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;proc&lt;/span&gt; &lt;span style=&#34;color:#a2f&#34;&gt;&amp;amp;rest&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;args&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Asks to enter random string as confirmation before executing PROC.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#a2f&#34;&gt;interactive&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#a2f&#34;&gt;let*&lt;/span&gt; ((&lt;span style=&#34;color:#b8860b&#34;&gt;pass&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;sarg/otp-for-confirm&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         (&lt;span style=&#34;color:#b8860b&#34;&gt;input&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;read-string&lt;/span&gt; (&lt;span style=&#34;color:#00a000&#34;&gt;format&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Enter %s if you wish to proceed: &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;pass&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#a2f&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#b8860b&#34;&gt;string=&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;input&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;pass&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        (&lt;span style=&#34;color:#00a000&#34;&gt;apply&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;proc&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;args&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;;; Apply the advice.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#b8860b&#34;&gt;advice-add&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;&amp;#39;ivy-telega-chat-with&lt;/span&gt; &lt;span style=&#34;color:#a2f&#34;&gt;:around&lt;/span&gt; &lt;span style=&#34;color:#00a000&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;confirm-advice&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    

    <item>
      <title>Exporting secrets from FreeOTP to Pass</title>
      <link>http://sarg.org.ru/blog/freeotp-to-pass/</link>
      <pubDate>Fri, 21 Sep 2018 00:00:00 +0000</pubDate>
      <author>sarg@sarg.org.ru (Sergey Trofimov)</author>
      <guid>http://sarg.org.ru/blog/freeotp-to-pass/</guid>
      <description>&lt;p&gt;I have broken my phone screen. Not a big deal but I use it for 2FA. While
replacement is on the way I will extract credentials from &lt;a href=&#34;https://freeotp.github.io/&#34;&gt;FreeOTP&lt;/a&gt; and import
them in &lt;a href=&#34;https://www.passwordstore.org/&#34;&gt;password store&lt;/a&gt;. Be aware that it is completeley against the idea of 2FA,
because now both password and otp are on the same device.&lt;/p&gt;
&lt;p&gt;So, first I need to find where FreeOTP stores OTP secrets. Android apps
usually use sqlite db for that, but not in this case. FreeOTP uses shared_prefs.&lt;/p&gt;
&lt;p&gt;Pull prefs from the phone (root needed).&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;adb root
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;adb pull /data/data/org.fedorahosted.freeotp/shared_prefs/tokens.xml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here is what they look like.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080&#34;&gt;&amp;lt;?xml version=&amp;#39;1.0&amp;#39; encoding=&amp;#39;utf-8&amp;#39; standalone=&amp;#39;yes&amp;#39; ?&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;lt;map&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;lt;string&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;name=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Amazon Web Services:sarg@organization&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;gt;&lt;/span&gt;{&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;algo&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;:&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;SHA1&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;,&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;counter&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;:0,&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;digits&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;:6,&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;issuerExt&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;:&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;Amazon Web Services&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;,&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;issuerInt&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;:&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;Amazon Web Services&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;,&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;label&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;:&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;sarg@organization&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;,&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;period&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;:30,&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;secret&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;:[52,19,105,64,67,-120,-45],&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;type&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;:&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;TOTP&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;}&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;lt;string&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;name=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;tokenOrder&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;gt;&lt;/span&gt;[&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;Amazon Web Services:sarg@organization&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;,&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;Google:sarg@sarg.org.ru&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;,&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;GitHub:sarg&lt;span style=&#34;color:#999;font-weight:bold&#34;&gt;&amp;amp;quot;&lt;/span&gt;]&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;lt;/map&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Storing JSON in XML - that&amp;rsquo;s a beaty. If you decode the value, it looks better:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;TOTP&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;secret&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#666&#34;&gt;52&lt;/span&gt;, &lt;span style=&#34;color:#666&#34;&gt;19&lt;/span&gt;, &lt;span style=&#34;color:#666&#34;&gt;105&lt;/span&gt;, &lt;span style=&#34;color:#666&#34;&gt;64&lt;/span&gt;, &lt;span style=&#34;color:#666&#34;&gt;67&lt;/span&gt;, &lt;span style=&#34;color:#666&#34;&gt;-120&lt;/span&gt;, &lt;span style=&#34;color:#666&#34;&gt;-45&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;period&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#666&#34;&gt;30&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;label&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;sarg@organization&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;issuerInt&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Amazon Web Services&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;issuerExt&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Amazon Web Services&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;digits&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#666&#34;&gt;6&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;counter&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#666&#34;&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#008000;font-weight:bold&#34;&gt;&amp;#34;algo&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;SHA1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now I need to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;parse xml&lt;/li&gt;
&lt;li&gt;extract json from xml&lt;/li&gt;
&lt;li&gt;extract secret from json and encode it with base32&lt;/li&gt;
&lt;li&gt;construct otpauth:// uri using details from json&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;URI format is described in google-authenticator &lt;a href=&#34;https://github.com/google/google-authenticator/wiki/Key-Uri-Format&#34;&gt;wiki&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Provision a TOTP key for user alice@google.com, to use with a service provided
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;by Example, Inc:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&amp;amp;issuer=Example
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For one-time scripts I prefer using python.
There is a handy library for dealing with html/xml - BeautifulSoup.
And I will consult with FreeOTP &lt;a href=&#34;https://github.com/freeotp/freeotp-android&#34;&gt;sources&lt;/a&gt; to get things right.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#!/usr/bin/env python3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;urllib.parse&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;base64&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;json&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#00f;font-weight:bold&#34;&gt;bs4&lt;/span&gt; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;import&lt;/span&gt; BeautifulSoup
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;inp &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a2f&#34;&gt;open&lt;/span&gt;(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;tokens.xml&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;soup &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; BeautifulSoup(inp, &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;lxml&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;for&lt;/span&gt; tag &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;in&lt;/span&gt; soup&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;find_all(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;string&amp;#39;&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# it&amp;#39;s a special setting, skip it&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt; tag[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;tokenOrder&amp;#39;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    token &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; json&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;loads(tag&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;text)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# secret is stored as signed byte array&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# so first make it unsigned by adding 256 modulo 256&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# and then convert to python&amp;#39;s bytearray&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    secret &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a2f&#34;&gt;bytearray&lt;/span&gt;(&lt;span style=&#34;color:#a2f&#34;&gt;map&lt;/span&gt;(&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;lambda&lt;/span&gt; x: (x&lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;256&lt;/span&gt;)&lt;span style=&#34;color:#666&#34;&gt;%&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;256&lt;/span&gt;, token[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;secret&amp;#39;&lt;/span&gt;]))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    issuer &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; token&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;get(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;issuerExt&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a2f&#34;&gt;print&lt;/span&gt;(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;otpauth://&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;{type}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;{issuer}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;?&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;{args}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;format(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a2f&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;token[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;type&amp;#39;&lt;/span&gt;]&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;lower(),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# issuer should be URL encoded&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        issuer&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;urllib&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;parse&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;quote(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;:&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;join(&lt;span style=&#34;color:#a2f&#34;&gt;filter&lt;/span&gt;(&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;None&lt;/span&gt;, (issuer, token[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;label&amp;#39;&lt;/span&gt;])))),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        args&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;urllib&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;parse&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;urlencode({
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;secret&amp;#39;&lt;/span&gt;: base64&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;b32encode(secret)&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;decode(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;algo  &amp;#39;&lt;/span&gt;: token[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;algo&amp;#39;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;digits&amp;#39;&lt;/span&gt;: token[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;digits&amp;#39;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;period&amp;#39;&lt;/span&gt;: token[&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;period&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        })
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;inp&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;close()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now what&amp;rsquo;s left is just to import everything into pass with &lt;code&gt;pass otp insert -e&lt;/code&gt;.
Or you can manually put &lt;code&gt;otpauth://&lt;/code&gt; string in an appropriate pass file. I did
the latter way, because my already existing entries have had another names.
Then check that everything went fine - &lt;code&gt;pass otp &#39;Amazon Web Services/sarg@organization&#39;&lt;/code&gt;&lt;/p&gt;</description>
    </item>
    
  </channel>
</rss>
