<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Hack on Noetic Nought</title>
    <link>https://punchagan.muse-amuse.in/tags/hack/</link>
    <description>Recent content in Hack on Noetic Nought</description>
    <generator>Hugo</generator>
    <language>en-US</language>
    <copyright>© 2006-2026 CC-BY-SA-4.0</copyright>
    <lastBuildDate>Wed, 20 Nov 2024 15:17:00 +0530</lastBuildDate>
    <atom:link href="https://punchagan.muse-amuse.in/tags/hack/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Restoring a broken Ubuntu upgrade</title>
      <link>https://punchagan.muse-amuse.in/blog/restoring-broken-ubuntu-upgrade/</link>
      <pubDate>Wed, 20 Nov 2024 15:17:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/restoring-broken-ubuntu-upgrade/</guid>
      <description>&lt;p&gt;A couple of weeks ago, &lt;a href=&#34;http://baali.muse-amuse.in&#34;&gt;Shantanu&lt;/a&gt; and I were discussing Ubuntu upgrades &amp;ndash; his&#xA;upgrade was borked and he ended up re-installing his system. I was celebrating&#xA;the fact that I never really had to throw away my OS installation entirely&#xA;since I switched to Ubuntu after getting tired of &lt;a href=&#34;https://punchagan.muse-amuse.in/blog/numpy-pacman-and-me/&#34;&gt;Arch Linux in 2011-12&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;And on cue, I had a really broken update on my dad&amp;rsquo;s laptop! It was really&#xA;broken &amp;ndash; no WiFi, no Ethernet connection, no GUI packages, etc.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-crash&#34;&gt;The crash&lt;/h2&gt;&#xA;&lt;p&gt;I started the update but forgot about it, promptly. My dad was semi-supervising&#xA;it, since he was using the laptop on-and-off. I came back to it a couple of&#xA;days later, and I ran an autoremove, assuming everything else in the install&#xA;went ok. Everything continued to work alright until some time later, we had to&#xA;restart the X server because it had hung up. And it never came back. And on a&#xA;full restart, no network &amp;ndash; both Ethernet and Wifi.&lt;/p&gt;&#xA;&lt;h2 id=&#34;chroot-to-the-rescue&#34;&gt;&lt;code&gt;chroot&lt;/code&gt; to the rescue!&lt;/h2&gt;&#xA;&lt;p&gt;Thankfully these are not the days when I had &lt;a href=&#34;https://punchagan.muse-amuse.in/blog/not-so-floppix/&#34;&gt;access to a single computer&lt;/a&gt;, and&#xA;crashing it meant running to a friend and using their computer to download&#xA;stuff. I quickly made a bootable USB on my laptop.&lt;/p&gt;&#xA;&lt;p&gt;I boot my dad&amp;rsquo;s laptop using the live distro and chroot to the installed OS&#xA;using the live distro. Live Ubuntu has Ethernet working, thankfully.&lt;/p&gt;&#xA;&lt;p&gt;For &lt;code&gt;apt-get install&lt;/code&gt; and &lt;code&gt;dist-upgrade&lt;/code&gt; to work correctly with the &lt;code&gt;chroot&lt;/code&gt;, I&#xA;had to &lt;a href=&#34;https://forum.manjaro.org/t/howto-chroot-from-or-into-any-linux-distribution/34071&#34;&gt;mount a bunch of volumes&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Due to some network manager changes in the update, the &lt;code&gt;chroot&lt;/code&gt; system still&#xA;wasn&amp;rsquo;t connecting to the internet. I probably should&amp;rsquo;ve looked at the&#xA;&lt;code&gt;resolv.conf&lt;/code&gt; file first, but ended up going the &lt;a href=&#34;https://wiki.ubuntu.com/OfflinePackageDownload&#34;&gt;offline package install&lt;/a&gt;&#xA;route&amp;hellip;&lt;/p&gt;&#xA;&lt;h2 id=&#34;offline-updates&#34;&gt;Offline updates&lt;/h2&gt;&#xA;&lt;p&gt;I generate a list of missing packages to be downloaded using the &lt;code&gt;--print-uris&lt;/code&gt;&#xA;flag to &lt;code&gt;apt-get&lt;/code&gt; on the &lt;code&gt;chroot&lt;/code&gt; system; And use &lt;code&gt;wget&lt;/code&gt; to download the&#xA;packages on the &amp;ldquo;live&amp;rdquo; system; Then copying these packages to&#xA;&lt;code&gt;/var/cache/apt/archives/&lt;/code&gt; gets the update to finish.&lt;/p&gt;&#xA;&lt;h2 id=&#34;but-more-missing-packages&#34;&gt;But more missing packages!&lt;/h2&gt;&#xA;&lt;p&gt;I rebooted into the installed OS, once &lt;code&gt;apt-get dist-upgrade&lt;/code&gt; seems to have&#xA;everything resolved. But, I still didn&amp;rsquo;t have a network! I had to &lt;code&gt;chroot&lt;/code&gt;&#xA;again into the system, and this time I figured out that there was an issue with&#xA;&lt;code&gt;resolv.conf&lt;/code&gt; being a broken soft-link which seemed to cause the broken network&#xA;(with Ethernet).&lt;/p&gt;&#xA;&lt;p&gt;For WiFi, I had to install proprietary drivers for the Broadcom wireless card&#xA;(&lt;code&gt;BCM43142 802.11b/g/n&lt;/code&gt;).&lt;/p&gt;&#xA;&lt;p&gt;I had to also install the &lt;code&gt;ubuntu-desktop&lt;/code&gt; and related packages that seem to&#xA;have gone missing, and on reboot everything was up and running!&lt;/p&gt;&#xA;&lt;h2 id=&#34;outro&#34;&gt;Outro&lt;/h2&gt;&#xA;&lt;p&gt;When I told Shantanu, I didn&amp;rsquo;t have to reinstall my Ubuntu from scratch doesn&amp;rsquo;t&#xA;mean that all my updates were flawless, and things never broke. I have had such&#xA;broken updates a few times &amp;ndash; network updates leaving the system in a broken&#xA;state after network connections died, Ubuntu upgrade being in a borked state&#xA;after the &lt;a href=&#34;https://ubuntu.com/security/CVE-2024-3094&#34;&gt;xz vulnerability was discovered&lt;/a&gt;, etc.&lt;/p&gt;&#xA;&lt;p&gt;Updates do fail. But, more often than not I&amp;rsquo;ve been able to restore things&#xA;thanks to &lt;code&gt;dpkg&lt;/code&gt; &amp;rsquo;s robustness and awesomness! And in some extreme cases,&#xA;reaching for &lt;code&gt;chroot&lt;/code&gt; to save myself.&lt;/p&gt;&#xA;&lt;p&gt;There&amp;rsquo;s probably nothing new to learn or discover in this post, but just some&#xA;help forum links that might come in handy, in future. In this age of AI&#xA;answers, it seemed nice to look through some old forum QAs and work things out&#xA;using them.&lt;/p&gt;&#xA;&lt;div style=&#34;font-size:small;&#34; class=&#34;reviewers&#34;&gt;&#xA;&lt;p&gt;Thanks to &lt;a href=&#34;http://baali.muse-amuse.in&#34;&gt;Shantanu&lt;/a&gt; and &lt;a href=&#34;https://x.com/kamalx&#34;&gt;Kamal&lt;/a&gt; for reading drafts of this post.&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>Responsive Auto Export for Org Hugo</title>
      <link>https://punchagan.muse-amuse.in/blog/responsive-auto-export-for-org-hugo/</link>
      <pubDate>Wed, 13 Nov 2024 00:17:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/responsive-auto-export-for-org-hugo/</guid>
      <description>&lt;p&gt;I use &lt;a href=&#34;https://github.com/kaushalmodi/ox-hugo/&#34;&gt;ox-hugo&lt;/a&gt; to &lt;a href=&#34;https://punchagan.muse-amuse.in/blog/deploying-hugo-drafts-simplified/&#34;&gt;write blog posts&lt;/a&gt; in org-mode and publish them using &lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt;. I&#xA;&lt;a href=&#34;https://punchagan.muse-amuse.in/blog/why-i-like-org-as-a-markup/&#34;&gt;enjoy using org-mode&lt;/a&gt; for any writing that I do, including blog posts (when I am&#xA;able to get myself to write them). After a long hiatus, I&amp;rsquo;ve been trying to get&#xA;back to blogging, as this post might have given away. But, ox-hugo&amp;rsquo;s &lt;a href=&#34;https://ox-hugo.scripter.co/doc/auto-export-on-saving/&#34;&gt;auto&#xA;export&lt;/a&gt; seemed much slower than I remember it being.&lt;/p&gt;&#xA;&lt;p&gt;Each time I hit save on my &lt;code&gt;blog-posts.org&lt;/code&gt; file, Emacs gets busy for about&#xA;10ish seconds exporting the post to Hugo markdown. And this is annoying because&#xA;I tend to hit &lt;code&gt;save-buffer&lt;/code&gt; multiple times while writing in &lt;code&gt;Emacs&lt;/code&gt; &amp;ndash; thanks,&#xA;muscle memory!&lt;/p&gt;&#xA;&lt;h2 id=&#34;enter-emacs-profiler&#34;&gt;Enter Emacs profiler&lt;/h2&gt;&#xA;&lt;p&gt;I was on a flight and had some time to dig into this. If I was online, I&#xA;probably would have looked through the README and/or the issue tracker, but I&#xA;&lt;a href=&#34;https://punchagan.muse-amuse.in/blog/how-i-learnt-to-use-emacs-profiler/&#34;&gt;jumped in&lt;/a&gt; with the handy &lt;a href=&#34;https://www.gnu.org/software/emacs/manual/html_node/elisp/Profiling.html&#34;&gt;Emacs profiler&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;The profiler-report showed that a big chunk of time was being spent in&#xA;&lt;code&gt;org-id-update-id-locations&lt;/code&gt; even before the actual export started. And then,&#xA;during the export, a bulk of the time was spent in&#xA;&lt;code&gt;org-hugo--get-pre-processed-buffer&lt;/code&gt;. Once I knew the problem areas, I started&#xA;poking around in the &lt;code&gt;ox-hugo&lt;/code&gt; code to &amp;ldquo;fix&amp;rdquo; these issues.&lt;/p&gt;&#xA;&lt;h2 id=&#34;turn-off-org-id-location-update&#34;&gt;Turn off Org ID location update&lt;/h2&gt;&#xA;&lt;p&gt;&lt;code&gt;org-id-update-id-locations&lt;/code&gt; scans a bunch of org-mode files and stores a&#xA;mapping of all the IDs of subtrees to their filenames. If you have a lot of org&#xA;subtrees this can take a while, even if none of them actually have IDs. It&#xA;turns out that I didn&amp;rsquo;t have any ID properties set, and this caused the &lt;a href=&#34;https://github.com/kaushalmodi/ox-hugo/blob/98421a1298adc6d80ce21b3cb5c951af818b27bf/ox-hugo.el#L4881-L4882&#34;&gt;update&#xA;function to run before every export&lt;/a&gt;!&lt;/p&gt;&#xA;&lt;p&gt;I simply added a new ID property on one of the subtrees in my blog-posts file&#xA;to prevent the ID updation from running on every export! I&amp;rsquo;m not sure how a&#xA;stale &lt;code&gt;org-id-locations&lt;/code&gt; value affects cross links, but at this stage of&#xA;writing I don&amp;rsquo;t care about the cross links. (spoiler: The next hack actually&#xA;nullifies any impact a stale value might have had!)&lt;/p&gt;&#xA;&lt;p&gt;Cutting down auto export time by 4-5 seconds is great! But, I&amp;rsquo;m still not happy&#xA;to wait for 5-6 seconds in the middle of writing my posts. Let&amp;rsquo;s look at the&#xA;other hotspot &amp;ndash; the buffer preprocessing!&lt;/p&gt;&#xA;&lt;h2 id=&#34;turn-off-buffer-preprocessing-maybe&#34;&gt;Turn off buffer preprocessing, maybe?&lt;/h2&gt;&#xA;&lt;p&gt;Currently, I don&amp;rsquo;t have any cross links between posts in my org-mode source.&#xA;So, I can turn off this feature completely by setting&#xA;&lt;code&gt;org-hugo--preprocess-buffer&lt;/code&gt; to &lt;code&gt;nil&lt;/code&gt;. Viola! Hitting &lt;code&gt;save-buffer&lt;/code&gt; doesn&amp;rsquo;t&#xA;freeze my Emacs any more. I can compose &amp;ldquo;100s of blog posts&amp;rdquo;™ in a flurry! ;)&lt;/p&gt;&#xA;&lt;p&gt;But, if I&amp;rsquo;m going to have these &amp;ldquo;100s of blog posts&amp;rdquo;, wouldn&amp;rsquo;t it be better to&#xA;have cross links? But, with preprocessing turned off when there are&#xA;cross-links, the &amp;ldquo;auto-export and build&amp;rdquo; workflow breaks. The variable&#xA;&lt;code&gt;org-hugo--preprocess-buffer&lt;/code&gt; MUST be non-nil to produce posts with &lt;strong&gt;valid&lt;/strong&gt;&#xA;cross-links. If not, the exported markdown file processed by &lt;code&gt;hugo&lt;/code&gt; ends up&#xA;having broken cross-links, which crashes &lt;code&gt;hugo serve&lt;/code&gt; and/or &lt;code&gt;hugo build&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Unsetting and setting the &lt;code&gt;org-hugo--preprocess-buffer&lt;/code&gt; variable for the&#xA;writing vs publishing phase, respectively, isn&amp;rsquo;t an ergonomic workflow. It&amp;rsquo;s&#xA;not an improvement over disabling and enabling the auto-export mode as needed.&#xA;I want to enjoy auto export with Hugo&amp;rsquo;s &lt;a href=&#34;https://gohugo.io/getting-started/usage/#livereload&#34;&gt;live reload&lt;/a&gt; feature.&lt;/p&gt;&#xA;&lt;h2 id=&#34;moar-workaround&#34;&gt;Moar workaround!&lt;/h2&gt;&#xA;&lt;p&gt;Looking through the code some more, I learnt &lt;a href=&#34;https://github.com/kaushalmodi/ox-hugo/blob/98421a1298adc6d80ce21b3cb5c951af818b27bf/ox-hugo.el#L2723&#34;&gt;&lt;code&gt;org-hugo-link&lt;/code&gt;&lt;/a&gt; first uses a&#xA;custom export handler, if one exists for a link&amp;rsquo;s protocol. I decided to piggy&#xA;back on this functionality and made up &lt;code&gt;hugo:&lt;/code&gt; protocol for cross-links.&lt;/p&gt;&#xA;&lt;p&gt;The &lt;code&gt;hugo&lt;/code&gt; link simply contains the &lt;code&gt;EXPORT_FILE_NAME&lt;/code&gt; of the linked blog post&#xA;i.e., name of the exported markdown file (without the .md extension) as the&#xA;&amp;lsquo;path&amp;rsquo; of the link. The custom protocol export handler can then generates a&#xA;&lt;code&gt;relref&lt;/code&gt; shortcode for Hugo to process in the exported markdown file.&lt;/p&gt;&#xA;&lt;p&gt;This nicely works around the need to preprocess my entire &lt;code&gt;blog-posts.org&lt;/code&gt;&#xA;buffer to generate &lt;strong&gt;valid&lt;/strong&gt; cross-links!&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-link-set-parameters&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;hugo&amp;#34;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;:export&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pc/org-hugo-link-export-to-md&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Export Hugo blog link to markdown file&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/org-hugo-link-export-to-md&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;path&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;backend&lt;/span&gt; &lt;span class=&#34;kp&#34;&gt;&amp;amp;optional&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;Export a link to a Hugo blog link in markdown format.&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;format&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;path: %s, desc: %s, backend: %s&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;path&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;backend&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cond&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;backend&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;md&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;equal&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-export-current-backend&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;hugo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;format&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;[%s]({{&amp;lt; relref \&amp;#34;%s\&amp;#34; &amp;gt;}})&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;error&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Cannot export Hugo link to non-Hugo backend&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;t&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;error&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Cannot export Hugo link to non-Hugo backend&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;outro&#34;&gt;Outro&lt;/h2&gt;&#xA;&lt;p&gt;I made a &lt;a href=&#34;https://github.com/punchagan/dot-doom/blob/c45f01e6b20275ce1df943855626af5c40cb626c/config.el#L541-L564&#34;&gt;simple helper&lt;/a&gt; to make it easier to insert these cross-links with the&#xA;&lt;code&gt;hugo:&lt;/code&gt; protocol. It simply looks through all the headlines with an&#xA;&lt;code&gt;EXPORT_FILE_NAME&lt;/code&gt; property, and allows it to be inserted as a link with the&#xA;&lt;code&gt;hugo:&lt;/code&gt; protocol.&lt;/p&gt;&#xA;&lt;p&gt;Now, cross-linking posts and publishing posts with cross-links are both a&#xA;breeze. Stay tuned for the &amp;ldquo;100s of blog posts&amp;rdquo; ™ I&amp;rsquo;m going to write!&lt;/p&gt;&#xA;&lt;div style=&#34;font-size:small;&#34; class=&#34;reviewers&#34;&gt;&#xA;&lt;p&gt;Thanks to &lt;a href=&#34;http://baali.muse-amuse.in&#34;&gt;Shantanu&lt;/a&gt; and &lt;a href=&#34;https://x.com/kamalx&#34;&gt;Kamal&lt;/a&gt; for reading drafts of this post.&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>Made in 2022</title>
      <link>https://punchagan.muse-amuse.in/blog/made-in-2022/</link>
      <pubDate>Wed, 08 Mar 2023 23:35:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/made-in-2022/</guid>
      <description>&lt;p&gt;Keeping with last year&amp;rsquo;s tradition, this post comes when we are almost 1/5th&#xA;through this year.&lt;/p&gt;&#xA;&lt;h2 id=&#34;2022-projects&#34;&gt;2022 projects&lt;/h2&gt;&#xA;&lt;dl&gt;&#xA;&lt;dt&gt;&lt;a href=&#34;https://github.com/punchagan/expense-tracker&#34;&gt;Expense Tracker&lt;/a&gt;&lt;/dt&gt;&#xA;&lt;dd&gt;I built a personal Expense Tracker over the month of&#xA;October using SQLite and Streamlit, because I wasn&amp;rsquo;t comfortable sharing my&#xA;financial data with a 3rd party. I&amp;rsquo;ve tried to keep it simple, so it&amp;rsquo;s not a&#xA;pain to use.  But, I&amp;rsquo;ve also tried to keep it extensible, for others to try&#xA;and use.&#xA;&lt;p&gt;The last few months have been quite busy personally, and I haven&amp;rsquo;t been able&#xA;to use it as much as I would like to, but hopefully things will settle down&#xA;soon.  A couple of things that I&amp;rsquo;d like to improve:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;The Sqlite file is stored locally, and the data is not synced between&#xA;different computers.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;The tagging/categorization of expenses is very manual, and a little bit&#xA;more automation would be handy.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/dd&gt;&#xA;&lt;dt&gt;&lt;a href=&#34;https://github.com/punchagan/artful-dodger/&#34;&gt;artful-dodger&lt;/a&gt;&lt;/dt&gt;&#xA;&lt;dd&gt;A Next.js project for hosting an art/photo gallery with&#xA;metadata stored in a Google Spreadsheet and images in a Google Drive (with an&#xA;optional CDN, recommended). I built this for a friend, who is experimenting&#xA;with creating &amp;ldquo;a more equitable model for curating, buying, and selling&#xA;art&amp;rdquo;. The gallery is currently in &amp;ldquo;private beta&amp;rdquo;, and I can&amp;rsquo;t link to&#xA;it. But, here&amp;rsquo;s a sample gallery &lt;a href=&#34;https://punchagan.github.io/artful-dodger/&#34;&gt;here&lt;/a&gt;, whose configuration lives &lt;a href=&#34;https://github.com/punchagan/artful-dodger/blob/main/.env.local.default&#34;&gt;here&lt;/a&gt;.&lt;/dd&gt;&#xA;&lt;dt&gt;&lt;a href=&#34;https://github.com/punchagan/ox-gist&#34;&gt;ox-gist&lt;/a&gt;&lt;/dt&gt;&#xA;&lt;dd&gt;I released my first Emacs MELPA package &amp;ndash; &lt;a href=&#34;https://melpa.org/#/ox-gist&#34;&gt;ox-gist&lt;/a&gt; &amp;ndash; an Orgmode&#xA;backend to export and update sub-trees and buffers to GitHub gists.  It was a&#xA;great experience contributing to MELPA.  I wrote a blog post about it &lt;a href=&#34;https://punchagan.muse-amuse.in/blog/ox-gist/&#34;&gt;too&lt;/a&gt;.&lt;/dd&gt;&#xA;&lt;dt&gt;&lt;a href=&#34;https://github.com/punchagan/android-dotfiles/tree/main/bin&#34;&gt;Termux scripts&lt;/a&gt;&lt;/dt&gt;&#xA;&lt;dd&gt;I&amp;rsquo;ve started using Termux on my Android phone and have&#xA;found the Text-to-Speech (TTS) API quite handy.  I&amp;rsquo;ve a couple of scripts on&#xA;my phone that lets me use TTS to read out contents on the clipboard or an&#xA;article from my browser.&lt;/dd&gt;&#xA;&lt;dt&gt;&lt;a href=&#34;https://github.com/india-ultimate/fantasy&#34;&gt;Fantasy League Site&lt;/a&gt;&lt;/dt&gt;&#xA;&lt;dd&gt;With help from a bunch of volunteers collecting and&#xA;validating data, &lt;a href=&#34;https://github.com/Joe2k&#34;&gt;Jonny&lt;/a&gt; and I built a &lt;a href=&#34;https://fantasy.indiaultimate.org/&#34;&gt;website&lt;/a&gt; for the Fantasy League for&#xA;Indian Ultimate State Championships. There was nothing technically&#xA;challenging about the project, but it just involved a lot of data cleaning&#xA;and co-ordination between the volunteers. The data was collected using pen&#xA;and paper, instead of a digital app for collecting the stats.  This made the&#xA;data cleaning and validation significantly harder. I&amp;rsquo;d definitely push for&#xA;digital data collection if people try to do something like this again.&lt;/dd&gt;&#xA;&lt;dt&gt;&lt;a href=&#34;https://github.com/punchagan/bookmarklets&#34;&gt;Bookmarklets&lt;/a&gt;&lt;/dt&gt;&#xA;&lt;dd&gt;A &lt;a href=&#34;https://punchagan.github.io/bookmarklets/&#34;&gt;web-page&lt;/a&gt; with a bunch of Bookmarklets from my browser&amp;rsquo;s&#xA;Bookmarks bar. I&amp;rsquo;ve had most of them around for a while, but putting them on&#xA;a web page makes it easy to share and find myself on other&#xA;browsers/computers.&lt;/dd&gt;&#xA;&lt;dt&gt;Music&lt;/dt&gt;&#xA;&lt;dd&gt;Unlike 2021, I&amp;rsquo;ve only been able to record a couple of songs. And&#xA;this year (2023) hasn&amp;rsquo;t been any better, so far. I hope I&amp;rsquo;ll be able to make&#xA;amends to this, soon, though.&lt;/dd&gt;&#xA;&lt;/dl&gt;&#xA;&lt;h2 id=&#34;review-of-2021-projects&#34;&gt;Review of 2021 projects&lt;/h2&gt;&#xA;&lt;dl&gt;&#xA;&lt;dt&gt;&lt;a href=&#34;https://github.com/punchagan/earworm/&#34;&gt;Earworm&lt;/a&gt;&lt;/dt&gt;&#xA;&lt;dd&gt;I didn&amp;rsquo;t make any updates to the package, not because it&amp;rsquo;s perfect&#xA;but because I didn&amp;rsquo;t use it much in 2022 &amp;ndash; thanks to how little I&amp;rsquo;ve been&#xA;able to record.&#xA;&lt;p&gt;While, writing this blog post I realized that workflow had a couple of&#xA;annoyances. I improved the code to fix them.&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;I need to move an audio file back-and-forth between my phone and my&#xA;laptop, one full round trip to add ID3 tags and cover image.  This makes&#xA;me put off uploading recorded files to the site.  Also, the new media file&#xA;needs to be named in a specific format.  I&amp;rsquo;ve added a new CLI subcommand&#xA;to automate all of this for me.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;I always need the full collection of the music files on the computer,&#xA;where I&amp;rsquo;m updating the site from. I can just &lt;code&gt;scp&lt;/code&gt; the existing site onto&#xA;my computer and merge the media directories.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/dd&gt;&#xA;&lt;dt&gt;&lt;a href=&#34;https://ukulele.muse-amuse.in/&#34;&gt;Ukulele Tutorials Aggregator&lt;/a&gt;&lt;/dt&gt;&#xA;&lt;dd&gt;The job of manually updating the site is a&#xA;lot of work, and I haven&amp;rsquo;t had the interest to keep doing it.&lt;/dd&gt;&#xA;&lt;dt&gt;RPi Server and Phone Backup&lt;/dt&gt;&#xA;&lt;dd&gt;The physical setup was accidentally dismantled&#xA;by folks I share my physical space with, and I haven&amp;rsquo;t been able to put back&#xA;everything in place, yet.  I&amp;rsquo;m hoping I&amp;rsquo;ll be able to get back to doing this&#xA;at some point this year.&lt;/dd&gt;&#xA;&lt;/dl&gt;&#xA;&lt;h2 id=&#34;outro&#34;&gt;Outro&lt;/h2&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve already built a couple of small things in 2023, and I hope I am able to&#xA;find some interesting things to do this year.&lt;/p&gt;&#xA;&lt;p&gt;Link to the &lt;a href=&#34;https://punchagan.muse-amuse.in/blog/made-in-2021/&#34;&gt;2021&lt;/a&gt; post.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Moving from Heroku to Fly.io</title>
      <link>https://punchagan.muse-amuse.in/blog/moving-from-heroku-to-fly-dot-io/</link>
      <pubDate>Sun, 06 Nov 2022 12:19:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/moving-from-heroku-to-fly-dot-io/</guid>
      <description>&lt;p&gt;A couple of months ago Heroku &lt;a href=&#34;https://blog.heroku.com/next-chapter&#34;&gt;announced&lt;/a&gt; their plan to &amp;ldquo;Focus on Mission&#xA;Critical&amp;rdquo; and shut down the free product plan. The ideas is to free up their&#xA;developer time to focus on the important stuff instead of fighting abuse of the&#xA;free plans. I&amp;rsquo;m surprised they invested in the free plans for so many years!&lt;/p&gt;&#xA;&lt;h2 id=&#34;my-heroku-apps&#34;&gt;My Heroku Apps&lt;/h2&gt;&#xA;&lt;p&gt;I have a bunch of apps on the free (Hobby dev) plan, and only app on the Hobby&#xA;Basic plan because it needed a bigger DB. All of these apps are small enough&#xA;that I could easily host all of them on my shared &lt;a href=&#34;https://www.hetzner.com/&#34;&gt;Hetzner server&lt;/a&gt;, where this&#xA;blog is hosted. But, I like using Heroku for services that I run for other&#xA;people. It makes access control and deployment much easier, and lets me invite&#xA;other people to help maintain apps easily, despite constraints like &lt;a href=&#34;https://devcenter.heroku.com/articles/heroku-postgres-plans#hobby-tier&#34;&gt;10k rows&lt;/a&gt; in&#xA;the Postgres DB and &lt;a href=&#34;https://devcenter.heroku.com/articles/free-dyno-hours&#34;&gt;Dyno sleeping&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Over the years of using Heroku, I ended up accumulating a bunch of small apps&#xA;on the service. Most of these apps aren&amp;rsquo;t actively being used any more and&#xA;didn&amp;rsquo;t feel worth the effort of moving.&lt;/p&gt;&#xA;&lt;p&gt;I decided to let most of the apps die, since they aren&amp;rsquo;t actively being&#xA;used. Only a couple of apps are used regularly enough to be worth keeping alive&#xA;&amp;ndash; &lt;a href=&#34;https://sotg.indiaultimate.org/&#34;&gt;SOTG Calculator&lt;/a&gt; and &lt;a href=&#34;https://rsvp.tiks-ultimate.in/features&#34;&gt;RSVP app&lt;/a&gt;. I turned on &lt;a href=&#34;https://devcenter.heroku.com/articles/maintenance-mode&#34;&gt;maintenance mode&lt;/a&gt; on the RSVP app&#xA;for a couple of days, as an experiment, and I had to bring back the services&#xA;due to &amp;ldquo;popular&amp;rdquo; demand.&lt;/p&gt;&#xA;&lt;h2 id=&#34;why-not-pay-heroku&#34;&gt;Why not pay Heroku?&lt;/h2&gt;&#xA;&lt;p&gt;I did consider just moving up to the Hobby basic plan and paying for running&#xA;the app. I wasn&amp;rsquo;t keen on investing numerous hours to get these apps to run&#xA;again. &lt;a href=&#34;https://instagram.com/akilesh.m&#34;&gt;Akilesh&lt;/a&gt; convinced me that the amount to pay Heroku could be collected&#xA;from the team and wouldn&amp;rsquo;t amount to much per person. I almost took this route.&lt;/p&gt;&#xA;&lt;p&gt;But, it bugged me that the amount we&amp;rsquo;d be paying Heroku could fund a couple of&#xA;turf practice sessions for the team. I could host the apps on my Hetzner server&#xA;&amp;ndash; we already pay enough for it. But, giving other people maintainer access to&#xA;apps is important and this was not straightforward with Hetzner.&lt;/p&gt;&#xA;&lt;p&gt;Also, the SOTG app couldn&amp;rsquo;t be funded this way.&lt;/p&gt;&#xA;&lt;h2 id=&#34;why-fly-dot-io&#34;&gt;Why Fly.io?&lt;/h2&gt;&#xA;&lt;p&gt;I ranted about this to my friends on Zulip and &lt;a href=&#34;https://github.com/rajaboja/&#34;&gt;Rajesh&lt;/a&gt; offered to help me as a&#xA;way to learn some devops stuff. I was more than happy to have someone to&#xA;discuss this stuff with and get some help.&lt;/p&gt;&#xA;&lt;p&gt;We decided to give &lt;a href=&#34;https://fly.io/&#34;&gt;Fly.io&lt;/a&gt; a try despite being skeptical about using yet another&#xA;free service. Their free Hobby plan includes 3GB of persistent storage space&#xA;(which neither of the apps currently use, but potentially could). They also&#xA;built &lt;a href=&#34;https://fly.io/blog/new-turboku/&#34;&gt;Turboku&lt;/a&gt; &amp;ndash; a tool to move apps from Heroku. It seemed worth giving a try,&#xA;and we could always fall back on Hetzner if it didn&amp;rsquo;t work out.&lt;/p&gt;&#xA;&lt;p&gt;We had a couple of months before the Heroku shutdown date, when I ranted about&#xA;this. Rajesh and I exchanged a few links and messages on how to potentially go&#xA;about doing this, when we got down to it. But, he got busy with other things&#xA;and now the deadline was only a month away. I decided to use the notes and do&#xA;the migration myself. I was glad I had the notes to refer to. The initial&#xA;&amp;ldquo;research&amp;rdquo; made the task seem less daunting.&lt;/p&gt;&#xA;&lt;h2 id=&#34;migrating-a-simple-app&#34;&gt;Migrating a simple app&lt;/h2&gt;&#xA;&lt;p&gt;I started with the simpler app first &amp;ndash; the &lt;a href=&#34;https://sotg.indiaultimate.org/&#34;&gt;SOTG app&lt;/a&gt;. I used the &lt;a href=&#34;https://fly.io/launch/heroku&#34;&gt;Turboku web&#xA;page&lt;/a&gt; and it worked pretty seemlessly! It copied over the environment variables&#xA;from Heroku and deployed the app.&lt;/p&gt;&#xA;&lt;p&gt;But, using the Turboku web page meant that I didn&amp;rsquo;t have a &lt;code&gt;fly.toml&lt;/code&gt; file to&#xA;do any future deployments. I used the &lt;code&gt;fly launch&lt;/code&gt; command to create a new app&#xA;and edited the &lt;code&gt;fly.toml&lt;/code&gt; file to point to the migrated app.&lt;/p&gt;&#xA;&lt;p&gt;Setting up the custom domain was pretty simple too, using the CLI. I just had&#xA;to run &lt;code&gt;fly certs add sotg.indiaultimate.org&lt;/code&gt; after changing the DNS entries to&#xA;point to &lt;code&gt;sotg-calculator.fly.dev&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;The whole thing felt quite simple and I was done in under an hour &amp;ndash; reading&#xA;the docs, installing the tool, trying out different things, getting it all&#xA;working. Everything. Quite impressive!&lt;/p&gt;&#xA;&lt;h2 id=&#34;migrating-a-bigger-app&#34;&gt;Migrating a bigger app&lt;/h2&gt;&#xA;&lt;p&gt;Encouraged by this, I started with the RSVP app. I didn&amp;rsquo;t think it would be&#xA;much harder than this, but I guess when there are a few more moving parts, it&amp;rsquo;s&#xA;hard to tell what could pop-up.&lt;/p&gt;&#xA;&lt;p&gt;I used the same approach for the migration &amp;ndash; Turboku web page to migrate from&#xA;Heroku and then ran the launch command to generate a &lt;code&gt;fly.toml&lt;/code&gt; file that I&#xA;edited to point to the deployed app.&lt;/p&gt;&#xA;&lt;p&gt;The deployment seemed to go fine, but the app wouldn&amp;rsquo;t come up. I looked at the&#xA;logs to find out that the app was getting &lt;a href=&#34;https://neo4j.com/developer/kb/linux-out-of-memory-killer/&#34;&gt;OOM killed&lt;/a&gt;. Fly.io provides half the&#xA;memory (256MB) that Heroku provided. But, I wasn&amp;rsquo;t expecting this tiny app to&#xA;need much more.&lt;/p&gt;&#xA;&lt;p&gt;I removed some default imports of large packages, but it didn&amp;rsquo;t really help&#xA;that much. I did consider reducing the Gunicorn&amp;rsquo;s &lt;code&gt;WEB_CONCURRENCY&lt;/code&gt; setting to&#xA;1, but didn&amp;rsquo;t want to take that route unless absolutely required. I looked&#xA;around the forums a little, and &lt;a href=&#34;https://community.fly.io/t/question-about-weird-deployment-size-on-fly/5677/2&#34;&gt;found&lt;/a&gt; that using a Dockerfile instead of the&#xA;buildpacks might improve the memory situation. And it did!&lt;/p&gt;&#xA;&lt;p&gt;Next, I moved to setting up the custom domain and it worked from the Fly.io&#xA;side seemlessly. But, the &lt;code&gt;flask_dance&lt;/code&gt; library was generating &lt;code&gt;http&lt;/code&gt; URLs in&#xA;it&amp;rsquo;s OAuth redirect URLs. The app already uses FlaskSSLify, but that didn&amp;rsquo;t&#xA;seem to be sufficient. After reading some &lt;a href=&#34;https://flask-dance.readthedocs.io/en/latest/proxies.html&#34;&gt;Flask dance&lt;/a&gt; and &lt;a href=&#34;https://flask.palletsprojects.com/en/latest/deploying/proxy_fix/&#34;&gt;Flask&lt;/a&gt; docs, I found&#xA;that Werkzeug&amp;rsquo;s &lt;code&gt;ProxyFix&lt;/code&gt; exists exactly for this!&lt;/p&gt;&#xA;&lt;p&gt;After dealing with these two unexpected problems, I got to the problem that I&#xA;was aware I had to tackle &amp;ndash; Fly.io doesn&amp;rsquo;t have support for cron jobs. The&#xA;RSVP app uses some scheduled jobs to periodically sync some metadata from&#xA;Google Drive, Calendar, etc.&lt;/p&gt;&#xA;&lt;p&gt;I took a hackish route to work around this. Using the &lt;a href=&#34;https://schedule.readthedocs.io/en/stable/&#34;&gt;schedule&lt;/a&gt; library, I wrote&#xA;a &lt;a href=&#34;https://github.com/thatte-idli-kaal-soup/rsvpapp/blob/master/scripts/cron.py&#34;&gt;&amp;ldquo;cron&amp;rdquo; script&lt;/a&gt; that would run the jobs on the desired schedule. I created a&#xA;duplicate app to run the cron service, even though it could potentially be run&#xA;as a different process on the same app. I didn&amp;rsquo;t want to risk any more OOM&#xA;kills on the web app. But, it can be a little bit more work to keep the&#xA;environment variables and other such things in sync between the two apps.&lt;/p&gt;&#xA;&lt;p&gt;I was quite excited about Fly.io having a datacenter in Madras and was swayed&#xA;by Fly.io&amp;rsquo;s marketing about running the app close to the users. I tried this&#xA;but the performance was terrible since the Mongo DB was in North Virginia. I&#xA;quickly switched back to using an East Coast region for Fly.io app too.&lt;/p&gt;&#xA;&lt;p&gt;But, while writing this blog post, I realized that I could move the DB to&#xA;India. I moved the DB to the AWS Mumbai datacenter, and the Fly.io app to the&#xA;Madras datacenter.&lt;/p&gt;&#xA;&lt;h2 id=&#34;all-s-well-that-ends-well&#34;&gt;All&amp;rsquo;s well that ends well&lt;/h2&gt;&#xA;&lt;p&gt;The app has been chugging along for a few days without any new hiccups. I&amp;rsquo;m&#xA;hoping things stay this way for the weeks and months to come, if not years.&lt;/p&gt;&#xA;&lt;p&gt;On the whole, I found the whole experience more beta-ish than deploying&#xA;something to Heroku. But, I&amp;rsquo;m quite happy with how the whole thing turned&#xA;out. I think things will get smoother with time &amp;ndash; with my growing familarity&#xA;with Fly.io and more people using their tools suggesting improvements.&lt;/p&gt;&#xA;&lt;p&gt;I am wary of depending on yet another Hobby plan, but neither of these apps&#xA;make any revenue and I&amp;rsquo;m not (yet) comfortable charging users for the small set&#xA;of features they provide.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;d like to hear stories of other people moving away from Heroku! Feel free to&#xA;reach out!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>GitHub Gists from Emacs Orgmode</title>
      <link>https://punchagan.muse-amuse.in/blog/ox-gist/</link>
      <pubDate>Tue, 26 Apr 2022 12:37:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/ox-gist/</guid>
      <description>&lt;p&gt;TL;DR: I released my first Emacs MELPA package &amp;ndash; &lt;a href=&#34;https://melpa.org/#/ox-gist&#34;&gt;ox-gist&lt;/a&gt; &amp;ndash; An Orgmode backend&#xA;to export and update sub-trees and buffers to GitHub gists.  It was a great&#xA;experience contributing to MELPA.&lt;/p&gt;&#xA;&lt;h2 id=&#34;motivation&#34;&gt;Motivation&lt;/h2&gt;&#xA;&lt;p&gt;I often share bits and pieces of my &lt;code&gt;journal.org&lt;/code&gt; file with others, mostly for&#xA;reading, some times for comments. The file contains different subtrees for each&#xA;day with subtrees for different topics, meetings, articles, etc.&lt;/p&gt;&#xA;&lt;p&gt;Orgmode lets you export subtrees to specific file names using the&#xA;&lt;code&gt;EXPORT_FILE_NAME&lt;/code&gt; property (and &lt;code&gt;FILE_NAME&lt;/code&gt; buffer export option when&#xA;exporting full buffers). It is easy to create these exported files on a&#xA;publicly accessible webserver using the power of &lt;a href=&#34;https://www.gnu.org/software/tramp/&#34;&gt;Emacs TRAMP mode&lt;/a&gt;.  For&#xA;instance, I often set the property to some thing like&#xA;&lt;code&gt;/ssh:muse-amuse.in:~/public_html/&amp;lt;filename&amp;gt;&lt;/code&gt; to publish stuff.&lt;/p&gt;&#xA;&lt;p&gt;But, exporting to HTML is a distraction some times because I start fiddling&#xA;with CSS and styling. Exporting to a simple org file doesn&amp;rsquo;t seem to cut it&#xA;because there&amp;rsquo;s no styling at all, and making longer exports hard to read in a&#xA;web-browser.  Exporting to a GitHub Gist is a nice middle ground because GitHub&#xA;renders Orgmode files reasonably well. Additionally, the comment functionality&#xA;is pretty handy.&lt;/p&gt;&#xA;&lt;p&gt;I could also directly use &lt;a href=&#34;https://github.com/defunkt/&#34;&gt;@defunkt&lt;/a&gt;&amp;rsquo;s excellent &lt;a href=&#34;https://github.com/defunkt/gist.el&#34;&gt;&lt;code&gt;gist.el&lt;/code&gt;&lt;/a&gt; to share stuff as&#xA;Gists.  I&amp;rsquo;ve used it in the past, and it works well when I don&amp;rsquo;t care about&#xA;having the contents of the Gist locally on my machine. It&amp;rsquo;s also quite easy to&#xA;update existing/old Gists in this scenario, since there&amp;rsquo;s a single &amp;ldquo;source of&#xA;truth&amp;rdquo; and &lt;code&gt;gist.el&lt;/code&gt; makes it quite easy to update Gists.&lt;/p&gt;&#xA;&lt;p&gt;But, this isn&amp;rsquo;t good enough when I want to have a &amp;ldquo;synced&amp;rdquo; copy of the text on&#xA;my machine.  Also, it doesn&amp;rsquo;t work very well when I want to share just a&#xA;subtree from my notes file, and not the entire file.  I&amp;rsquo;ve to export the&#xA;subtree to a temporary Orgmode buffer and then create a Gist from that buffer.&lt;/p&gt;&#xA;&lt;h2 id=&#34;hackish-wrapper-around-gist-dot-el&#34;&gt;Hackish wrapper around &lt;code&gt;gist.el&lt;/code&gt;&lt;/h2&gt;&#xA;&lt;p&gt;A couple or so years ago, I wrote a wrapper around &lt;code&gt;gist.el&lt;/code&gt; to let me post&#xA;Orgmode subtrees as a Gist and also update them when I edited these subtrees&#xA;locally.  There was no support for exporting entire buffers since that wasn&amp;rsquo;t&#xA;my use-case.  This wrapper code was just a part of my &lt;code&gt;.emacs&lt;/code&gt; and worked&#xA;reasonably well for me.&lt;/p&gt;&#xA;&lt;p&gt;A few weeks ago, I ended up procrastinating on writing and sharing notes for a&#xA;discussion with a friend, and extracted this wrapper as a separate package &amp;ndash;&#xA;&lt;code&gt;org2gist&lt;/code&gt; &amp;ndash; to make it easy for other people to use.&lt;/p&gt;&#xA;&lt;h2 id=&#34;melpa-submission-and-feedback&#34;&gt;MELPA submission and feedback&lt;/h2&gt;&#xA;&lt;p&gt;I &lt;a href=&#34;https://github.com/melpa/melpa/pull/7940&#34;&gt;submitted&lt;/a&gt; this as a package to &lt;a href=&#34;https://melpa.org/&#34;&gt;MELPA&lt;/a&gt; while being skeptical about whether it&#xA;would be accepted.  I wasn&amp;rsquo;t sure if my thin wrapper around &lt;code&gt;gist.el&lt;/code&gt; would&#xA;meet MELPA&amp;rsquo;s criteria for a &amp;ldquo;Reasonably innovative package&amp;rdquo;:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;MELPA provides a curated set of Emacs Lisp packages, not an exhaustive list&#xA;of every single Emacs Lisp file ever created. By default, MELPA maintainers&#xA;will reject packages that duplicate functionality provided by existing&#xA;packages. Please try to improve existing packages instead of creating new&#xA;ones when possible.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;It was a pleasant surprise to get very helpful reviews from the MELPA&#xA;maintainers.  They not only thought the package was good enough to include in&#xA;MELPA, but also looked at it&amp;rsquo;s code and gave great feedback &amp;mdash; not just basic&#xA;quality checks before accepting the package into MELPA.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;m pretty sure mainting a package repository like MELPA is a lot of work, but&#xA;as an end-user it mostly just worked for me and I never really gave it much&#xA;thought.  It was eye-opening to submit the package to MELPA and see first-hand&#xA;the care and effort the maintainers put into what goes into the repository.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/riscy/&#34;&gt;@riscy&lt;/a&gt; (a MELPA maintainer) &lt;a href=&#34;https://github.com/melpa/melpa/pull/7940#issuecomment-1080036663&#34;&gt;suggested&lt;/a&gt; a different approach that I hadn&amp;rsquo;t&#xA;thought of &amp;mdash; turning the wrapper into an &lt;a href=&#34;https://orgmode.org/manual/Exporting.html&#34;&gt;Orgmode Export backend&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;current-version-ox-gist&#34;&gt;Current version: &lt;code&gt;ox-gist&lt;/code&gt;&lt;/h2&gt;&#xA;&lt;p&gt;It turned out to be a great idea which I ended up implementing.  The user&#xA;interface became much cleaner, since it used the Orgmode Export UI.  And it&#xA;also forced me to &amp;ldquo;complete&amp;rdquo; the feature-set by adding support for exporting&#xA;entire Orgmode buffers to GitHub Gists, not just subtrees.&lt;/p&gt;&#xA;&lt;p&gt;The package now adds an Orgmode export backend that lets you export a subtree&#xA;or the whole buffer as a GitHub Gist, similar to how you&amp;rsquo;d export to HTML or&#xA;LaTeX from Orgmode. The GitHub Gist ID is saved for each exported buffer or&#xA;subtree and is to update a Gist when re-exporting an already exported subtree&#xA;or buffer.&lt;/p&gt;&#xA;&lt;h2 id=&#34;outro&#34;&gt;Outro&lt;/h2&gt;&#xA;&lt;p&gt;The package has now been added to MELPA as &lt;a href=&#34;https://github.com/punchagan/ox-gist&#34;&gt;&lt;code&gt;ox-gist&lt;/code&gt;&lt;/a&gt;.  Feel free to give it a&#xA;spin and give feedback directly to me or on the &lt;a href=&#34;https://github.com/punchagan/ox-gist/issues&#34;&gt;issue tracker&lt;/a&gt;!&lt;/p&gt;&#xA;&lt;p&gt;I don&amp;rsquo;t know if anyone else would find the package useful and use it, though,&#xA;MELPA tells me that 20-odd people atleast downloaded it.  I&amp;rsquo;m happy this code&#xA;may be to a handful of people.&lt;/p&gt;&#xA;&lt;p&gt;Also, I now have a new found appreciation for MELPA and the work put into it by&#xA;the maintainers.  I&amp;rsquo;m glad I took the time out to submit this package to MELPA.&lt;/p&gt;&#xA;&lt;div style=&#34;font-size:small;&#34; class=&#34;reviewers&#34;&gt;&#xA;&lt;p&gt;Thanks to &lt;a href=&#34;http://baali.muse-amuse.in&#34;&gt;Shantanu&lt;/a&gt; for reading drafts and helping me restructure this post.&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>Made in 2021</title>
      <link>https://punchagan.muse-amuse.in/blog/made-in-2021/</link>
      <pubDate>Thu, 24 Feb 2022 02:23:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/made-in-2021/</guid>
      <description>&lt;p&gt;Some things I made in 2021:&lt;/p&gt;&#xA;&lt;dl&gt;&#xA;&lt;dt&gt;&lt;a href=&#34;https://github.com/punchagan/earworm/&#34;&gt;Earworm&lt;/a&gt;&lt;/dt&gt;&#xA;&lt;dd&gt;A static site generator to listen to audio (and video?) files in a&#xA;directory. I use it to host a couple of simple websites for music files. It&#xA;also happens to be the first package I uploaded to PyPI despite writing&#xA;Python for many years.&lt;/dd&gt;&#xA;&lt;dt&gt;&lt;a href=&#34;https://ukulele.muse-amuse.in/&#34;&gt;Ukulele Tutorials Aggregator&lt;/a&gt;&lt;/dt&gt;&#xA;&lt;dd&gt;Inspired by &lt;a href=&#34;https://ukealong.com/&#34;&gt;Ukealong.com&lt;/a&gt;, I set out to create&#xA;an aggregator for Ukulele Tutorials for Indian songs. I&amp;rsquo;ve, with help from&#xA;&lt;a href=&#34;https://twitter.com/kamalx&#34;&gt;Kamal&lt;/a&gt;, populated about 300 songs on the site. I haven&amp;rsquo;t been able to keep up&#xA;with maintaing it, after an initial bunch of work. I&amp;rsquo;ve wanted to automate&#xA;more of the workflow, but haven&amp;rsquo;t yet.&lt;/dd&gt;&#xA;&lt;dt&gt;RPi Server and Phone Backup&lt;/dt&gt;&#xA;&lt;dd&gt;I&amp;rsquo;ve started to use a Raspberry Pi to backup&#xA;data from my phone and laptop to a personal Hard disk. I&amp;rsquo;ve &lt;a href=&#34;https://github.com/punchagan/ansible-raspberry-pi&#34;&gt;ansible scripts&lt;/a&gt;&#xA;to reproduce the RPi&amp;rsquo;s setup, and some &lt;a href=&#34;https://github.com/punchagan/sync-rpi&#34;&gt;scripts to &amp;ldquo;sync&amp;rdquo;&lt;/a&gt; my phone&amp;rsquo;s data&#xA;every few hours, when it&amp;rsquo;s on the same network. There&amp;rsquo;s a lot more that I&#xA;need here, before I can ditch cloud backups of important things.&lt;/dd&gt;&#xA;&lt;dt&gt;Music&lt;/dt&gt;&#xA;&lt;dd&gt;I made covers of about 10 songs on the Ukulele, that I shared with&#xA;some friends. I&amp;rsquo;ve ways to go before I&amp;rsquo;m comfortable sharing them on the web,&#xA;publicly.&lt;/dd&gt;&#xA;&lt;/dl&gt;&#xA;&lt;p&gt;I&amp;rsquo;m glad to have had the energy, time and resources to be able to spend time&#xA;working on some fun things despite everything that 2021 had in store for&#xA;us. Let&amp;rsquo;s see what 2022 has in store!&lt;/p&gt;&#xA;&lt;p&gt;PS: This post is quite late into 2022, but it&amp;rsquo;s an excuse to post something to&#xA;a blog that&amp;rsquo;s not seen any updates since the middle of 2020.&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;Hat tip to Bryan Braun whose &lt;a href=&#34;https://www.bryanbraun.com/2022/01/11/made-in-2021/&#34;&gt;post&lt;/a&gt; inspired me to write this&lt;/em&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Deploying Hugo Drafts, simplified</title>
      <link>https://punchagan.muse-amuse.in/blog/deploying-hugo-drafts-simplified/</link>
      <pubDate>Sun, 31 May 2020 17:19:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/deploying-hugo-drafts-simplified/</guid>
      <description>&lt;p&gt;This is a follow-up post to my last post, &lt;a href=&#34;https://punchagan.muse-amuse.in/blog/deploying-hugo-drafts&#34;&gt;Deploying Hugo Drafts&lt;/a&gt;. Kaushal Modi,&#xA;the author of &lt;a href=&#34;https://github.com/kaushalmodi/ox-hugo&#34;&gt;ox-hugo&lt;/a&gt; (a tool that lets you compose in org-mode and use Hugo to&#xA;export), let me know about the &lt;a href=&#34;https://gohugo.io/content-management/build-options/&#34;&gt;build options&lt;/a&gt; in Hugo.&lt;/p&gt;&#xA;&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;Have you looked at the new _build options: &lt;a href=&#34;https://t.co/Nj8Uefis6Q&#34;&gt;https://t.co/Nj8Uefis6Q&lt;/a&gt;. I haven&amp;#39;t used them yet, but looks like they fit your use case.&lt;/p&gt;&amp;mdash; Kaushal (@kaushalmodi) &lt;a href=&#34;https://twitter.com/kaushalmodi/status/1266761525286653952?ref_src=twsrc%5Etfw&#34;&gt;May 30, 2020&lt;/a&gt;&lt;/blockquote&gt;&#xA;&lt;script async src=&#34;https://platform.twitter.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;&#xA;&#xA;&#xA;&lt;p&gt;The build options in Hugo let you configure building a post for different use&#xA;cases like render a post but hide it in lists, or don&amp;rsquo;t render separate pages&#xA;for posts and only show them in lists, etc.&lt;/p&gt;&#xA;&lt;p&gt;To use these build options for my use case &amp;ndash; being able to share draft post&#xA;links with friends, without them appearing in the index page or RSS feed &amp;ndash; I&#xA;just need to add the following to my draft blog posts!&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;_build&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;render&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But, how do I do this with &lt;code&gt;ox-hugo&lt;/code&gt;? I know &lt;code&gt;ox-hugo&lt;/code&gt; doesn&amp;rsquo;t yet have this&#xA;feature, for sure, because Kaushal mentioned that he hasn&amp;rsquo;t tried it out yet.&lt;/p&gt;&#xA;&lt;p&gt;I checked to see if I could use the &lt;code&gt;EXPORT_HUGO_CUSTOM_FRONT_MATTER&lt;/code&gt; property&#xA;to get it to generate this extra metadata for each blog post. But that didn&amp;rsquo;t&#xA;work. The property assumes all the arguments to it are top level front matter&#xA;keys and values, which is good enough for &amp;ldquo;normal&amp;rdquo; use cases.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;EDIT &lt;span class=&#34;timestamp-wrapper&#34;&gt;&lt;span class=&#34;timestamp&#34;&gt;[2020-05-31 Sun]&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;: I previously manually created the &lt;code&gt;drafts&lt;/code&gt; directory with&#xA;the &lt;code&gt;_index.md&lt;/code&gt;, but Kaushal pointed me to &lt;a href=&#34;https://twitter.com/kaushalmodi/status/1267066389996724229&#34;&gt;more docs&lt;/a&gt;, again! :) There&amp;rsquo;s also an&#xA;&lt;a href=&#34;https://github.com/kaushalmodi/ox-hugo/issues/358&#34;&gt;issue&lt;/a&gt; for adding an easier way to add these build options from ox-hugo.&lt;/p&gt;&#xA;&lt;p&gt;I created a subtree like this in my org file, that creates the&#xA;&lt;code&gt;drafts/_index.md&lt;/code&gt; file with the required front matter and build options.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gh&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;gs&#34;&gt; Drafts&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;:PROPERTIES:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;&lt;span class=&#34;cs&#34;&gt;:EXPORT_FILE_NAME: _index&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cs&#34;&gt;:EXPORT_HUGO_SECTION: drafts&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cs&#34;&gt;:EXPORT_HUGO_CUSTOM_FRONT_MATTER: yaml&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cs&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;:END:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;#+begin_src &lt;/span&gt;&lt;span class=&#34;cs&#34;&gt;yaml&lt;/span&gt;&lt;span class=&#34;c&#34;&gt; :front_matter_extra t&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;_build&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;render&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;publishResources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cascade&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;_build&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;render&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;#+end_src&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The build options for the index page turn off publishing and showing it in&#xA;lists. With the &lt;code&gt;cascade&lt;/code&gt; option, we can get the options to all the children &amp;ndash;&#xA;any files created in the &lt;code&gt;drafts&lt;/code&gt; directory, but also override the &lt;code&gt;render&lt;/code&gt;&#xA;option to be true. In other words, the configuration above would translate to&#xA;adding the following to &lt;em&gt;every draft post&lt;/em&gt;:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;A&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;How-to&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;on&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Hugo&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Drafts&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;_build&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;render&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;publishResources&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, I just need to make sure that all my draft posts are created in this&#xA;&lt;code&gt;drafts&lt;/code&gt; directory. &lt;code&gt;ox-hugo&lt;/code&gt; allows doing this by simply using the&#xA;&lt;code&gt;EXPORT_HUGO_SECTION&lt;/code&gt; property on my post subtree. I added this additional&#xA;property to my helper function that I use to create hugo blog posts from any&#xA;subtree.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gh&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;gs&#34;&gt; DRAFT A How-to on Hugo Drafts&lt;/span&gt;&lt;span class=&#34;ge&#34;&gt; :blogging:hack:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;:PROPERTIES:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;&lt;span class=&#34;cs&#34;&gt;:EXPORT_FILE_NAME: how-to-hugo-drafts&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cs&#34;&gt;:EXPORT_HUGO_SECTION: drafts&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cs&#34;&gt;:EXPORT_DATE: [2020-05-31 Sun 16:51]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cs&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;:END:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;m now all set to publish draft posts without requiring to use &lt;code&gt;rsync&lt;/code&gt; and two&#xA;&lt;code&gt;hugo&lt;/code&gt; builds. :) Publishing a draft post would need me to remove the &lt;code&gt;DRAFT&lt;/code&gt;&#xA;todo keyword, like before, but additionally also remove the&#xA;&lt;code&gt;:EXPORT_HUGO_SECTION:&lt;/code&gt; property on the subtree. This should be quite quick to&#xA;do, or pretty easy to put into an interactive function if required.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Deploying Hugo Drafts</title>
      <link>https://punchagan.muse-amuse.in/blog/deploying-hugo-drafts/</link>
      <pubDate>Sat, 30 May 2020 19:07:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/deploying-hugo-drafts/</guid>
      <description>&lt;p&gt;&lt;strong&gt;Update &lt;span class=&#34;timestamp-wrapper&#34;&gt;&lt;span class=&#34;timestamp&#34;&gt;[2020-05-31 Sun 17:23]&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;: I published a &lt;a href=&#34;https://punchagan.muse-amuse.in/blog/deploying-hugo-drafts-simplified&#34;&gt;simpler workflow&lt;/a&gt; for this, using&#xA;Hugo&amp;rsquo;s build options that I wasn&amp;rsquo;t aware of, because they are relatively new.&lt;/p&gt;&#xA;&lt;p&gt;A few friends and I run a weekly writing club similar to &lt;a href=&#34;https://github.com/sursh/writing-club&#34;&gt;this&lt;/a&gt;. Once we have our&#xA;drafts ready, we usually share them for reviews, etc.&lt;/p&gt;&#xA;&lt;p&gt;Previously, I used to use &lt;a href=&#34;https://getnikola.com&#34;&gt;Nikola&lt;/a&gt;, and it&amp;rsquo;s default behaviour is what worked well&#xA;for this workflow &amp;ndash; share the posts URL with reviewers, but the post shouldn&amp;rsquo;t&#xA;appear in the feed, post list, etc.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;If you set the status metadata field of a post to &lt;code&gt;draft&lt;/code&gt;, it will not be shown&#xA;in indexes and feeds. It will be compiled, and if you deploy it it will be made&#xA;available, so use with care. If you wish your drafts to be not available in your&#xA;deployed site, you can set &lt;code&gt;DEPLOY_DRAFTS = False&lt;/code&gt; in your configuration.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;I moved to using Hugo a few years ago. By default, it doesn&amp;rsquo;t publish the draft&#xA;posts, but you could ask it to do so using the &lt;code&gt;--buildDrafts&lt;/code&gt; option. But, that&#xA;doesn&amp;rsquo;t do what I want &amp;ndash; draft posts are treated just like any other post, and&#xA;they appear in the feeds, post list, etc.&lt;/p&gt;&#xA;&lt;p&gt;Given how fast &lt;code&gt;hugo&lt;/code&gt; builds are, though, it is pretty easy to hack-up the&#xA;behaviour I want.&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Run a build with drafts, say to &lt;code&gt;dev&lt;/code&gt; directory.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;DEV_DIR&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;dev&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Build drafts to dev dir&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;hugo --cleanDestinationDir -D -d &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;DEV_DIR&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &amp;gt; /dev/null&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Run a build without drafts, to &lt;code&gt;public&lt;/code&gt; directory.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PUBLIC_DIR&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;public&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;hugo --cleanDestinationDir -d &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;PUBLIC_DIR&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Copy the drafts from the &lt;code&gt;dev&lt;/code&gt; build to the &lt;code&gt;public&lt;/code&gt; build&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;rsync -ri --ignore-existing &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;DEV_DIR&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;/ &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;PUBLIC_DIR&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Deploy the &lt;code&gt;public&lt;/code&gt; build&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;The code above is &lt;a href=&#34;https://github.com/punchagan/dotfiles/blob/3652a6be42c776c6d1771e6cd46acadb2cafe295/bin/publish-hugo-drafts.sh&#34;&gt;here&lt;/a&gt; as a single script. &lt;a href=&#34;https://github.com/punchagan/punchagan.muse-amuse.in/blob/fdc80a61e28290c1c4a48a437bc77ec3fda811f5/deploy.sh&#34;&gt;Here&lt;/a&gt; is the full deployment script&#xA;for my blog.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>My New Standing Desk</title>
      <link>https://punchagan.muse-amuse.in/blog/my-new-standing-desk/</link>
      <pubDate>Thu, 27 Dec 2018 10:48:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/my-new-standing-desk/</guid>
      <description>&lt;p&gt;There is so much popular-science out there that describes sitting as the new&#xA;smoking. But, there&amp;rsquo;s also some research that talk about standing all day not&#xA;being good for the heart, etc. &lt;a href=&#34;https://www.healthline.com/health-news/debate-over-standing-vs-sitting-at-your-desk&#34;&gt;This article&lt;/a&gt; refers to a lot of research that&#xA;present both sides of the coin.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;m currently leaning towards switching positions regularly, rather than staying&#xA;in a single posture for hours together. Standing or sitting &amp;ndash; keep moving, keep&#xA;taking breaks. But, standing makes it slightly easier to get more movement -&#xA;just removing the need to get up from that chair, seems to help.&lt;/p&gt;&#xA;&lt;p&gt;Some years ago, I built myself another make-shift standing desk, but didn&amp;rsquo;t end&#xA;up using it - because it turned out to be not sufficiently big and comfortable&#xA;to work on.&lt;/p&gt;&#xA;&lt;img src=&#34;https://punchagan.muse-amuse.in/ox-hugo/standing-desk-old-bucket.jpeg&#34; alt=&#34;standing-desk-old-bucket.jpeg&#34; height=&#34;200px&#34; /&gt;&#xA;&lt;img src=&#34;https://punchagan.muse-amuse.in/ox-hugo/standing-desk-old-laptop.jpeg&#34; alt=&#34;standing-desk-old-laptop.jpeg&#34; height=&#34;200px&#34; /&gt;&#xA;&lt;p&gt;I have been looking around on the Internet to buy myself a standing desk. But,&#xA;they are either &lt;a href=&#34;https://www.amazon.in/SONGMICS-Standing-Adjustable-Workstation-Converter/dp/B075WRJDMZ&#34;&gt;super expensive&lt;/a&gt;, or &lt;a href=&#34;https://oristand.co/&#34;&gt;not&lt;/a&gt; &lt;a href=&#34;https://www.amazon.in/Spark-Ergodriven-Perfect-Standing-Medium/dp/B01GGNV6VQ&#34;&gt;adjustable&lt;/a&gt; enough to ensure the right&#xA;ergonomics. Given there&amp;rsquo;s so much being written against sitting, I&amp;rsquo;d have&#xA;expected there to be enough demand for these desks to bring down their prices!&lt;/p&gt;&#xA;&lt;p&gt;Last week, I built another desk, which feels much more sturdy than the previous&#xA;one. It&amp;rsquo;s also much more easy to move around (within the house), and a breeze to&#xA;assemble and disassemble. Again, I re-purposed some &amp;ldquo;furniture&amp;rdquo; lying around.&lt;/p&gt;&#xA;&lt;img src=&#34;https://punchagan.muse-amuse.in/ox-hugo/standing-desk-table.jpg&#34; alt=&#34;standing-desk-table.jpg&#34; height=&#34;300px&#34; /&gt;&#xA;&lt;img src=&#34;https://punchagan.muse-amuse.in/ox-hugo/standing-desk-floor.jpg&#34; alt=&#34;standing-desk-floor.jpg&#34; height=&#34;300px&#34; /&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve been using it only for a few days now. I&amp;rsquo;ll probably make another post with&#xA;my experiences of using it. I plan to set it on the floor and use it as a squat&#xA;desk, when I&amp;rsquo;m tired of standing. Let&amp;rsquo;s see how it goes!&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;p&gt;Thanks &lt;a href=&#34;http://baali.muse-amuse.in/&#34;&gt;Shantanu Choudhary&lt;/a&gt; for reading a draft of this post.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Software development practices for sports teams</title>
      <link>https://punchagan.muse-amuse.in/blog/software-development-practices-sports-teams/</link>
      <pubDate>Sun, 23 Sep 2018 11:31:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/software-development-practices-sports-teams/</guid>
      <description>&lt;h2 id=&#34;motivation&#34;&gt;Motivation&lt;/h2&gt;&#xA;&lt;p&gt;A few weeks ago, I came across &lt;a href=&#34;https://www.youtube.com/watch?v=SHOVVnRB4h0&#34;&gt;a talk on Mob programming&lt;/a&gt; &amp;mdash; a technique for&#xA;working on a software project as a team, that was accidentally discovered by a&#xA;team trying to figure out how to work well together. The speaker lets us in on&#xA;how they stumbled on it, and how they fine-tuned it to make it more effective&#xA;while being relaxed and enjoyable.&lt;/p&gt;&#xA;&lt;p&gt;A few days before that, I shared &lt;a href=&#34;http://daydreamsinruby.com/getting-feedback/&#34;&gt;a post&lt;/a&gt; on &amp;ldquo;getting feedback (as a software&#xA;developer)&amp;rdquo; with my &lt;a href=&#34;https://www.youtube.com/watch?v=zEKnqFBajiI&#34;&gt;Ultimate Frisbee&lt;/a&gt; team-mates and it seemed to resonate with&#xA;them. I&amp;rsquo;m often looking at things happening in my sports team from a software&#xA;guy&amp;rsquo;s perspective, since I spend a lot of time being the software guy. But, I&#xA;rarely, if ever, directly share these thoughts and ideas with my team-mates.&lt;/p&gt;&#xA;&lt;p&gt;But, the mob programming talk inspired me to make a conscious effort to look for&#xA;software development patterns that could be adopted by &lt;a href=&#34;https://thatteidlikaalsoup.team/&#34;&gt;our (sports) team&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Most players on our team have been playing Ultimate for a while now (2-5 years).&#xA;So, we have more problems due to miscommunication and everyone not being on the&#xA;same page, than we have due to lack of skills or knowledge. When someone on the&#xA;team does not understand the plan, the whole plan goes for a toss.&lt;/p&gt;&#xA;&lt;p&gt;How do we make sure that everyone understands what the team is trying to do and&#xA;is able to contribute their bit to the team&amp;rsquo;s plans and success? How do we make&#xA;playing with each other as enjoyable as it can be?&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&amp;ldquo;The object isn&amp;rsquo;t to make art, it&amp;rsquo;s to be in that wonderful state which makes&#xA;art inevitable.&amp;rdquo; &amp;mdash; Robert Henri&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;some-ideas-for-adoption&#34;&gt;Some ideas for adoption&lt;/h2&gt;&#xA;&lt;p&gt;Here are some ideas that, I think, could be adopted by our team. Some of these&#xA;are things that teams, including ours, do in some shape or form. But,&#xA;identifying and naming would make it easier for people to talk about them and&#xA;develop a common understanding of why and how to do them.&lt;/p&gt;&#xA;&lt;h3 id=&#34;ubiquitous-language&#34;&gt;Ubiquitous Language&lt;/h3&gt;&#xA;&lt;p&gt;Eric Evans, in his book Domain Driven Design, talks about building a &lt;a href=&#34;https://martinfowler.com/bliki/UbiquitousLanguage.html&#34;&gt;Ubiquitous&#xA;language&lt;/a&gt; in the team. It grows as the team&amp;rsquo;s understanding of the problem grows,&#xA;and helps the team communicate clearly throughout the development cycle.&lt;/p&gt;&#xA;&lt;p&gt;Our team plays a lot of zone defense, and it usually works well for us But, it&#xA;wasn&amp;rsquo;t working particularly well, during one of the tournaments last year.&#xA;Luckily, we had &lt;a href=&#34;https://www.instagram.com/monsieurmoby/&#34;&gt;Moby&lt;/a&gt; playing with us, and he asked us some probing questions&#xA;around the objective of the play and the roles of each of the players. With just&#xA;a short chat and a few small adjustments, the zone became way more effective.&#xA;Essentially, we built a common understanding of the objective of the defense and&#xA;brought everyone onto the same page.&lt;/p&gt;&#xA;&lt;p&gt;Ultimate teams use a lot of lingo &amp;ndash; a lot. New players just pick it up by&#xA;osmosis, at practice, from the senior folks. This works most of the time, except&#xA;when it doesn&amp;rsquo;t. Each person on the team has a slightly different understanding&#xA;of what a term means, and the difference is sometimes big enough to cause a plan&#xA;to fail due to miscommunication. Spending time building a common understanding&#xA;would make the team communicate and operate more effectively. Practicing game&#xA;scenarios is essentially a way of doing this, but it would be worth thinking&#xA;about and discussing the terms and the language being used.&lt;/p&gt;&#xA;&lt;p&gt;Off-field lingo should also be clarified using a similar process &amp;ndash; for&#xA;instance, what does &amp;ldquo;good sideline support&amp;rdquo; mean? What does giving or not giving&#xA;&amp;ldquo;feedback on the field&amp;rdquo; mean?&lt;/p&gt;&#xA;&lt;h3 id=&#34;sprints&#34;&gt;Sprints&lt;/h3&gt;&#xA;&lt;p&gt;Agile development recommends continuous development of software. Often software&#xA;teams use 2-4 week development cycles, called &lt;a href=&#34;http://wiki.c2.com/?ScrumSprint&#34;&gt;sprints&lt;/a&gt;. For each sprint, the team&#xA;sets itself a goal, and the whole team prioritizes tasks and makes decisions&#xA;in-line with this goal.&lt;/p&gt;&#xA;&lt;p&gt;Sports teams would also benefit from sprints &amp;ndash; short and focused practice&#xA;cycles, where everyone on the team is aware of the team&amp;rsquo;s goal. This would make&#xA;it much easier for players to help each other out. Also, players can align their&#xA;individual goals with the team goal, making practices much more effective.&lt;/p&gt;&#xA;&lt;h3 id=&#34;retrospectives&#34;&gt;Retrospectives&lt;/h3&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;At regular intervals, the team reflects on how to become more effective, then&#xA;tunes and adjusts its behavior accordingly. &amp;mdash; The Agile Manifesto&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Most Ultimate teams do some kind of post-practice retrospectives, though, they&#xA;don&amp;rsquo;t call it that. These retrospectives are a discussion of the good, bad and&#xA;the ugly. Usually, no conscious decisions are made about what practices are&#xA;working well for the team, and what should be taken forward to upcoming ones.&lt;/p&gt;&#xA;&lt;p&gt;Slightly longer term retrospectives would be quite useful too. If a team adopts&#xA;the idea of sprints, each new sprint should start with a retrospective of the&#xA;last one and planning for the next.&lt;/p&gt;&#xA;&lt;p&gt;A retrospective&amp;rsquo;s participants are expected to follow the &lt;a href=&#34;http://retrospectivewiki.org/index.php?title=The_Prime_Directive&#34;&gt;prime directive&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Regardless of what we discover, we understand and truly believe that everyone&#xA;did the best job they could, given what they knew at the time, their skills and&#xA;abilities, the resources available, and the situation at hand. &amp;mdash; Norm Kerth,&#xA;&lt;em&gt;Project Retrospectives: A Handbook for Team Review&lt;/em&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Internalising this would be really helpful especially during post-tournament&#xA;retrospectives, where emotions can run high &amp;ndash; it would keep the discussion&#xA;positive and focused on identifying problems and finding solutions, rather than&#xA;spiraling into blame games, defensive arguments, etc.&lt;/p&gt;&#xA;&lt;h3 id=&#34;daily-stand-ups&#34;&gt;Daily Stand-ups&lt;/h3&gt;&#xA;&lt;p&gt;Agile teams &lt;a href=&#34;https://www.mountaingoatsoftware.com/agile/scrum/meetings/daily-scrum&#34;&gt;gather each day&lt;/a&gt; at the start of the work-day, to let each know about&#xA;the progress of the work-items. The team tries to help each other get rid of the&#xA;impediments to progress.&lt;/p&gt;&#xA;&lt;p&gt;Ultimate teams could also benefit operating in this style &amp;ndash; everyone shares&#xA;with each other what they are working on, and the problems in their learning.&#xA;This would make it easier for others to look out for things to help with.&#xA;Team-mates would limit themselves to giving feedback to the thing that a player&#xA;is working on.&lt;/p&gt;&#xA;&lt;p&gt;Players setting themselves a small number of clear focus points would also force&#xA;them to consciously think about and work on their game more effectively.&lt;/p&gt;&#xA;&lt;h3 id=&#34;face-to-face-communication&#34;&gt;Face-to-face communication&lt;/h3&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;The most efficient and effective method of conveying information to and within a&#xA;development team is face-to-face conversation. &amp;mdash; The Agile Manifesto&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;As our team has grown larger over the years, more and more communication has&#xA;moved to the WhatsApp group. Keeping everyone informed via face-to-face&#xA;communication, at this team size needs a lot of co-ordination and planning, and&#xA;the time at practice is considered to be too precious to be spent talking and&#xA;not practicing.&lt;/p&gt;&#xA;&lt;p&gt;But, clearly WhatsApp doesn&amp;rsquo;t seem like the best medium to have discussions.&#xA;Discussions rarely, if ever, happen on our groups. It often just seems to be&#xA;information dissemination. Using a &lt;a href=&#34;http://zulipchat.com/hello&#34;&gt;better communication tool&lt;/a&gt; could mitigate a&#xA;few of these problems, but face-to-face discussions have other benefits. They&#xA;bring about a greater sense of belonging to the team and increase buy-in into&#xA;the team&amp;rsquo;s plans.&lt;/p&gt;&#xA;&lt;h3 id=&#34;unit-tests-vs-dot-integration-tests&#34;&gt;Unit tests vs. Integration tests&lt;/h3&gt;&#xA;&lt;p&gt;Practice games are helpful to gauge if a team is playing well together and if&#xA;its plans are working. This seems analogous to &lt;a href=&#34;http://wiki.c2.com/?IntegrationTest&#34;&gt;integration tests&lt;/a&gt; &amp;mdash; checking&#xA;that we have functional software, end-to-end.&lt;/p&gt;&#xA;&lt;p&gt;But, in the early stages of development, it&amp;rsquo;s common to write &lt;a href=&#34;http://wiki.c2.com/?UnitTest&#34;&gt;unit-tests&lt;/a&gt; &amp;ndash;&#xA;tests to ensure that each of the individual components works well in isolation.&#xA;An analogous thing would be to have individual evaluations to help players&#xA;identify weak areas, and to measure progress in those areas. It would also&#xA;prevent players from slipping on important &amp;ldquo;indicators&amp;rdquo;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;other-ideas-to-think-about&#34;&gt;Other ideas to think about&lt;/h2&gt;&#xA;&lt;p&gt;Some ideas that I find interesting, but don&amp;rsquo;t yet know if and how they can be&#xA;adopted by sports teams are below.&lt;/p&gt;&#xA;&lt;h3 id=&#34;mob-programming&#34;&gt;Mob programming&lt;/h3&gt;&#xA;&lt;p&gt;In a &lt;a href=&#34;https://www.agilealliance.org/resources/experience-reports/mob-programming-agile2014/&#34;&gt;mob programming session&lt;/a&gt;, everyone on the team is working on the same&#xA;computer, in the same room, at the same time. This seems tremendously&#xA;ineffective at the face of it, but turns out to be a good way to produce high&#xA;quality software, quickly.&lt;/p&gt;&#xA;&lt;h3 id=&#34;hammock-driven-development&#34;&gt;Hammock driven development&lt;/h3&gt;&#xA;&lt;p&gt;Bugs are incredibly expensive to be found and fixed in production software. They&#xA;are cheaper to fix in the development phase. But, the design phase is the best&#xA;place to fix them.&lt;/p&gt;&#xA;&lt;p&gt;Rich Hickey &lt;a href=&#34;https://www.youtube.com/watch?v=f84n5oFoZBc&#34;&gt;recommends&lt;/a&gt; feeding a lot of information about the problem you are&#xA;trying to solve to your waking mind, so that your background mind can feed off&#xA;of it while you are asleep, and make useful connections.&lt;/p&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Build projects around motivated individuals. Give them the environment and&#xA;support they need, and trust them to get the job done.  &amp;mdash; The Agile manifesto&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;This sounds exactly like what players in our team need too. The captains and the&#xA;mentors in the team should work towards providing the environment and the&#xA;support everyone on the team needs, and trust them to do the job.&lt;/p&gt;&#xA;&lt;div style=&#34;font-size:small;&#34; class=&#34;reviewers&#34;&gt;&#xA;&lt;p&gt;Thanks Meghana Iyer, &lt;a href=&#34;https://twitter.com/cloud9trt/&#34;&gt;Ravitheja Tetali&lt;/a&gt;, &lt;a href=&#34;http://baali.muse-amuse.in/&#34;&gt;Shantanu Choudhary&lt;/a&gt;, &lt;a href=&#34;https://twitter.com/vandith&#34;&gt;Vandith PSR&lt;/a&gt;, &lt;a href=&#34;https://varunrn.wordpress.com/&#34;&gt;Varun&#xA;Rangarajan&lt;/a&gt; and Vivek Krishnaswamy for reading drafts of this post and giving&#xA;helpful suggestions.&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>Where do the Children Play (in Bangalore)</title>
      <link>https://punchagan.muse-amuse.in/blog/where-do-the-children-play-in-bangalore/</link>
      <pubDate>Mon, 12 Feb 2018 13:11:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/where-do-the-children-play-in-bangalore/</guid>
      <description>&lt;p&gt;A bunch of us have recently started playing Badminton regularly (on weekends),&#xA;in Bangalore. We use &lt;a href=&#34;https://playo.co/&#34;&gt;Playo&lt;/a&gt; to book a court to play on. But, all of us live in&#xA;different parts of the city, and it&amp;rsquo;s often difficult to find a convenient place&#xA;to play. Often, we end up in bad courts because we don&amp;rsquo;t pay enough attention to&#xA;the ratings, while focusing on trying to find a court in a convenient location.&lt;/p&gt;&#xA;&lt;p&gt;To help make this search easier, I built a &lt;a href=&#34;https://punchagan.github.io/playo-find-venue/&#34;&gt;small web app&lt;/a&gt; that shows the venues&#xA;from Playo on a map, and then allows you to specify the locations of players,&#xA;and the radius (in km) that they are willing to travel. Hopefully, we end up&#xA;finding a good court in the overlapping region. Clicking on the venue marker&#xA;allows you to jump to the Playo booking page for that venue. The source is&#xA;available &lt;a href=&#34;https://github.com/punchagan/playo-find-venue/&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;figure&gt;&lt;img src=&#34;https://punchagan.muse-amuse.in/images/playo-find.jpg&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;I usually go with &lt;a href=&#34;http://leafletjs.com/&#34;&gt;leaflet&lt;/a&gt; when I want to do map related stuff. This is the&#xA;first time I used &lt;a href=&#34;https://developers.google.com/maps/documentation/javascript/&#34;&gt;Google APIs&lt;/a&gt;, and it was a pretty decent experience.&lt;/li&gt;&#xA;&lt;li&gt;I also ended up using the &lt;a href=&#34;https://developers.google.com/url-shortener/&#34;&gt;Google URL shortener API&lt;/a&gt; to make it easier to share&#xA;URLs. The entire state of the app is being saved in the URL fragment, so that&#xA;URLs are shareable, but it makes them long and ugly. Short URLs seemed like a&#xA;good workaround.&lt;/li&gt;&#xA;&lt;li&gt;I got most of it working with vanilla javascript, until I started doing things&#xA;where I felt it would be nice to have a light-weight two-way data and view&#xA;binding library. I ended up trying &lt;a href=&#34;http://knockoutjs.com/&#34;&gt;knockoutjs&lt;/a&gt; for the first time, and enjoyed&#xA;using it.&lt;/li&gt;&#xA;&lt;li&gt;The data for Playo venues is updated everyday using a &lt;a href=&#34;https://docs.travis-ci.com/user/cron-jobs/&#34;&gt;cron job that runs on&#xA;Travis&lt;/a&gt;. So, the ratings of venues should be pretty up-to-date.&lt;/li&gt;&#xA;&lt;li&gt;But, Playo allows players to rate venues overall, and not by sport. So, it may&#xA;so happen that the venue is a decent one overall, and has good facilities for&#xA;some other sport, but the badminton courts are still bad. But, some venues are&#xA;badminton only, and in those cases the ratings are more useful.&lt;/li&gt;&#xA;&lt;li&gt;It should be pretty easy to make the app &lt;a href=&#34;https://github.com/punchagan/playo-find-venue/blob/68a39a1f0ed0e13f59a529fb28853bad360b95ba/js/places.js#L90&#34;&gt;fetch data for other things&lt;/a&gt; like&#xA;restaurants/movie theaters, to make this app do more than just help find Playo&#xA;venues.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;To Moar Badminton!&lt;/p&gt;&#xA;&lt;iframe width=&#34; 700&#34; height=&#34; 500&#34; src=&#34;https://www.youtube.com/embed/PiiZrZTrOFY?rel=0&amp;amp;hd=1&amp;amp;wmode=transparent&#34;&gt;&lt;/iframe&gt;&#xA;</description>
    </item>
    <item>
      <title>Multiple remotes with nullmailer</title>
      <link>https://punchagan.muse-amuse.in/blog/multiple-remotes-with-nullmailer/</link>
      <pubDate>Sat, 18 Nov 2017 04:50:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/multiple-remotes-with-nullmailer/</guid>
      <description>&lt;p&gt;&lt;strong&gt;UPDATE 2018-08-20&lt;/strong&gt;: Moved away from nullmailer&lt;/p&gt;&#xA;&lt;p&gt;I updated my OS and &lt;code&gt;nullmailer&lt;/code&gt; possibly got updated, and this hack no longer&#xA;works. I&amp;rsquo;ve switched to &lt;code&gt;msmtp&lt;/code&gt; with a file based queue that I implemented&#xA;myself. &lt;code&gt;msmtp&lt;/code&gt; can be invoked with the &lt;code&gt;--read-recipient-from&lt;/code&gt; argument, to&#xA;choose the correct right mail server based on the from address.&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;p&gt;This a reference for future-me, and possibly someone pulling off an all-nighter&#xA;trying to get &lt;code&gt;nullmailer&lt;/code&gt; to use the correct &amp;ldquo;remote&amp;rdquo;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-is-nullmailer-and-why-use-it&#34;&gt;What is nullmailer and why use it?&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/bruceg/nullmailer&#34;&gt;Nullmailer&lt;/a&gt; is a simple mail transfer agent that can forward mail to a remote&#xA;mail server (or a bunch of them).&lt;/p&gt;&#xA;&lt;p&gt;I use Emacs to send email, and it can be configured to talk to a remote SMTP&#xA;server to send email. But, this blocks Emacs until the email is sent and the&#xA;connection closed. This is annoying, and having &lt;code&gt;nullmailer&lt;/code&gt; installed locally&#xA;basically lets Emacs delegate this job without blocking.&lt;/p&gt;&#xA;&lt;h2 id=&#34;why-multiple-remotes&#34;&gt;Why multiple remotes?&lt;/h2&gt;&#xA;&lt;p&gt;I have multiple email accounts, and I&amp;rsquo;d like to use the correct remote server&#xA;for sending email based on the FROM address.&lt;/p&gt;&#xA;&lt;p&gt;I expected &lt;code&gt;nullmailer&lt;/code&gt; to have some configuration to be able to specify this.&#xA;But, it turns out that &lt;code&gt;nullmailer&lt;/code&gt; just forwards the email to all the&#xA;configured remotes &lt;a href=&#34;https://github.com/bruceg/nullmailer/blob/master/src/send.cc#L382-L410&#34;&gt;until one of them succeeds&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;how-do-we-then-send-email-from-the-correct-remote-smtp-server&#34;&gt;How do we, then, send email from the correct remote SMTP server?&lt;/h2&gt;&#xA;&lt;p&gt;Currently, I have two remotes - my personal domain (&lt;code&gt;@muse-amuse.in&lt;/code&gt;) and GMail.&lt;/p&gt;&#xA;&lt;p&gt;Having GMail as the first remote in &lt;code&gt;nullmailer&lt;/code&gt;&amp;rsquo;s configuration wouldn&amp;rsquo;t let me&#xA;send emails from my personal domain. GMail seems to agree to send the email&#xA;coming from &lt;code&gt;@muse-amuse.in&lt;/code&gt;, but overwrite the MAIL FROM address and change it&#xA;to my GMail address.&lt;/p&gt;&#xA;&lt;p&gt;So, &lt;code&gt;@muse-amuse.in&lt;/code&gt; has to be the first remote. But, this server also seemed to&#xA;accept and send emails with a &lt;code&gt;@gmail.com&lt;/code&gt; &lt;code&gt;FROM&lt;/code&gt; address. This was causing&#xA;emails sent from my GMail ID to go into spam, as expected.&lt;/p&gt;&#xA;&lt;p&gt;I had to reconfigure this mail server to reject relaying mails that didn&amp;rsquo;t&#xA;belong to the correct domain names &amp;ndash; i.e., reject relaying emails which had&#xA;&lt;code&gt;@gmail.com&lt;/code&gt; in the &lt;code&gt;FROM&lt;/code&gt; address.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;smtpd_sender_restrictions&lt;/code&gt; had to modified to have &lt;code&gt;reject_sender_login_reject&lt;/code&gt;&#xA;along with other values, and the &lt;code&gt;smtpd_sender_login_maps&lt;/code&gt; had to be set to&#xA;allow only the &lt;code&gt;@muse-amuse.in&lt;/code&gt; domain. &lt;a href=&#34;https://serverfault.com/questions/318334/how-to-enforce-sender-address-to-be-logged-in-userexample-org-in-postfix&#34;&gt;This serverfault answer&lt;/a&gt; explains this in&#xA;more detail.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Emacs frame as a pop-up input</title>
      <link>https://punchagan.muse-amuse.in/blog/emacs-frame-as-a-pop-up-input/</link>
      <pubDate>Thu, 14 Sep 2017 22:26:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/emacs-frame-as-a-pop-up-input/</guid>
      <description>&lt;p&gt;I wanted to try using a dialog box/pop-up window as a prompt to remind me to&#xA;periodically make journal entries.  I had the following requirements:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Simple, light-weight dialog box that allows text of arbitrary length&lt;/li&gt;&#xA;&lt;li&gt;Ability to launch the dialog from the shell&lt;/li&gt;&#xA;&lt;li&gt;Ability to have some placeholder or template text, each time the dialog is shown&lt;/li&gt;&#xA;&lt;li&gt;Save the input text to a specific &lt;code&gt;org-mode&lt;/code&gt; file&lt;/li&gt;&#xA;&lt;li&gt;Write as little code of my own, as possible, to do this&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;I had initially thought about using a tool like &lt;code&gt;zenity&lt;/code&gt;, or write a simple&#xA;dialog box in Python using &lt;code&gt;Qt&lt;/code&gt;, &lt;code&gt;wx&lt;/code&gt; or even &lt;code&gt;tk&lt;/code&gt;, and then yank the input text&#xA;at the desired location. This probably wouldn&amp;rsquo;t have turned out to be too hard,&#xA;but getting things to look and work exactly the way I wanted would have required&#xA;more code than I was willing to write or maintain.&lt;/p&gt;&#xA;&lt;p&gt;After avoiding doing this for a while, I finally realized that I could simply&#xA;use Emacs with a new frame with the appropriate dimensions, and with the correct&#xA;file/buffer open to the desired location. This would&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;eliminate the need for me to write the UI myself&lt;/li&gt;&#xA;&lt;li&gt;eliminate the need to do text manipulation in code, to yank it at the right&#xA;place, in the right form. By directly opening up the editor at the required&#xA;location, the onus is on me (as a text inputting user) to put it in, the way I&#xA;want it.&lt;/li&gt;&#xA;&lt;li&gt;additionally provide me the comfort of being able to write with the full power&#xA;of Emacs - keybindings and all that jazz.&lt;/li&gt;&#xA;&lt;li&gt;let me leverage &lt;code&gt;elisp&lt;/code&gt; to do essentially whatever I want with the buffer&#xA;being displayed as the dialog box.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;I ended up with a command that looks something like this&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;emacsclient -c -n&lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;            -F &lt;span class=&#34;s1&#34;&gt;&amp;#39;((title . &amp;#34;Title&amp;#34;) (left . (+ 550)) (top . (+ 400)) (width . 110) (height . 12))&amp;#39;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;            -e &lt;span class=&#34;s1&#34;&gt;&amp;#39;(pc/open-journal-buffer)&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;figure&gt;&lt;img src=&#34;https://punchagan.muse-amuse.in/images/emacs-frame.png&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;This worked pretty nicely, except for the fact that with gnome-shell, the pop-up&#xA;frame doesn&amp;rsquo;t always appear raised. It often gets hidden in the Emacs windows&#xA;group, and the whole idea of the pop-up acting as a reminder goes for a toss!&#xA;But, thanks to &lt;a href=&#34;https://askubuntu.com/a/288483&#34;&gt;this Ask Ubuntu post&lt;/a&gt;, I could fix this pretty easily.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;emacsclient -c -n&lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;            -F &lt;span class=&#34;s1&#34;&gt;&amp;#39;((title . &amp;#34;Title&amp;#34;) (left . (+ 550)) (top . (+ 400)) (width . 110) (height . 12))&amp;#39;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;            -e &lt;span class=&#34;s1&#34;&gt;&amp;#39;(progn (pc/open-journal-buffer) (raise-frame) (x-focus-frame (selected-frame)))&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>Create a Public Jupyter Server, quickly!</title>
      <link>https://punchagan.muse-amuse.in/blog/create-a-public-jupyter-server-quickly/</link>
      <pubDate>Thu, 25 Aug 2016 00:00:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/create-a-public-jupyter-server-quickly/</guid>
      <description>&lt;p&gt;I create public Jupyter notebooks once in a while, to collaborate with a&#xA;friend, or to make it easier for myself to work with data on a remote machine.&lt;/p&gt;&#xA;&lt;p&gt;Each time I need to look up the &lt;a href=&#34;http://jupyter-notebook.readthedocs.io/en/latest/public_server.html&#34;&gt;docs&lt;/a&gt;, and manually set-up a few things, before&#xA;I can start using the notebook.&lt;/p&gt;&#xA;&lt;p&gt;I just wrote a bash script that does the following, quickly -&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Install Jupyter into a temporary virtualenv&lt;/li&gt;&#xA;&lt;li&gt;Create certificate files&lt;/li&gt;&#xA;&lt;li&gt;Start the server with https enabled and a password&lt;/li&gt;&#xA;&lt;li&gt;Delete all temporary files, when the server is shutdown&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;script src=&#34;https://gist-it.appspot.com/github/punchagan/dot-files/blob/master/bin/jupyter-server.sh&#34;&gt;&lt;/script&gt;&#xA;&lt;p&gt;You can get it &lt;a href=&#34;https://github.com/punchagan/dot-files/blob/master/bin/jupyter-server.sh&#34;&gt;here&lt;/a&gt;, if you&amp;rsquo;d like to use it.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Better styling bookmarklet</title>
      <link>https://punchagan.muse-amuse.in/blog/better-styling-bookmarklet/</link>
      <pubDate>Tue, 07 Jun 2016 14:39:01 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/better-styling-bookmarklet/</guid>
      <description>&lt;p&gt;Some sites that I like a lot for their content, have zero styling on them.&#xA;I find it pretty hard to read when the lines are long and I have to read all&#xA;the way on my screen.&lt;/p&gt;&#xA;&lt;p&gt;I had a simple bookmarklet until now that just changed the width of the page.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getElementsByTagName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;body&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;setAttribute&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;style&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;width: 600px&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href=&#34;https://twitter.com/kamalx&#34;&gt;Kamal&lt;/a&gt; shared with me &lt;a href=&#34;http://bettermotherfuckingwebsite.com&#34;&gt;a recommendation&lt;/a&gt; for 7 simple styling rules that will make&#xA;pages easier to read. I liked them, and modified my bookmarklet to use these&#xA;rules now.&lt;/p&gt;&#xA;&lt;figure&gt;&lt;img src=&#34;../../images/better-websites.gif&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;Drag and drop the link below onto your bookmarks bar if you want to use it.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a style=&#34;border: 0.05em dashed; padding: 0.5em;&#34; href=&#39;javascript:void(function(){style = document.createElement(&#34;style&#34;); document.head.appendChild(style); style.sheet.insertRule(&#34;body{ margin:40px auto; max-width:650px; line-height:1.6; font-size:18px; color:#444; padding:0 10px; }&#34;); style.sheet.insertRule(&#34;h1,h2,h3{ line-height:1.2 }&#34;)}())&#39;&gt;Better website&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;The code in a readable format is below.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// Create new stylesheet&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// Create the &amp;lt;style&amp;gt; tag&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;style&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;createElement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;style&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// Add the &amp;lt;style&amp;gt; element to the page&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;head&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;appendChild&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;style&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// Add rules from bettermotherfuckingwebsite.com&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;sheet&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;style&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;sheet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;sheet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;insertRule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;body{ margin:40px auto; max-width:650px; line-height:1.6; font-size:18px; color:#444; padding:0 10px; }&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;sheet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;insertRule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h1,h2,h3{ line-height:1.2 }&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;})();&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Update &lt;span class=&#34;timestamp-wrapper&#34;&gt;&lt;span class=&#34;timestamp&#34;&gt;[2016-06-07 Tue]&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;: &lt;a href=&#34;https://twitter.com/baali_&#34;&gt;baali&lt;/a&gt; pointed me to Firefox&amp;rsquo;s &lt;a href=&#34;https://support.mozilla.org/en-US/kb/firefox-reader-view-clutter-free-web-pages&#34;&gt;Reader View&lt;/a&gt; which works well too.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Reading-time based scheduling</title>
      <link>https://punchagan.muse-amuse.in/blog/reading-time-based-scheduling/</link>
      <pubDate>Mon, 06 Jun 2016 00:00:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/reading-time-based-scheduling/</guid>
      <description>&lt;p&gt;I had posted a link to an poem written on Medium on a Slack channel that I use&#xA;with friends.  A friend said that she liked the fact that the Slack article&#xA;preview had the reading time from Medium in it.  She could decide whether or&#xA;not she wanted to read the poem or any other article at that moment.&lt;/p&gt;&#xA;&lt;p&gt;This gave me the idea for a reading time extension for my &lt;a href=&#34;https://www.chromium.org/getting-involved/download-chromium&#34;&gt;browser&lt;/a&gt;, or my &lt;a href=&#34;https://github.com/skeeto/elfeed&#34;&gt;feed&#xA;reader&lt;/a&gt; or my &lt;a href=&#34;https://pinboard.in&#34;&gt;bookmarks&lt;/a&gt; &amp;ndash; my reading list.  The first version should be able to&#xA;compute or extract the reading time for an article or a tab in my browser, and&#xA;index them.  I want to be able to specify the amount of time I will be able to&#xA;spend reading, and be presented with something from my reading list.  I think&#xA;this would help with scheduling the reading of longer articles, and also to&#xA;actually help me get through my reading list.&lt;/p&gt;&#xA;&lt;p&gt;Reading time estimates that use heuristics based on word-count may not really&#xA;work, and may do &lt;a href=&#34;https://medium.com/@fchimero/this-should-only-take-a-minute-or-four-probably-e38bb7bf2adf#.mvkd09m6m&#34;&gt;more harm than good&lt;/a&gt;.  But, it may still be worth a try to see&#xA;if it helps my reading habits in any way.  A quick search pointed me to &lt;a href=&#34;https://chrome.google.com/webstore/detail/readism-article-reading-t/bmiolhceebkeljaikojgcoeefblcihje&#34;&gt;this&#xA;extension&lt;/a&gt;, that can give the reading time for any page but doesn&amp;rsquo;t really do&#xA;what I want.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Elfeed hook to fetch full content</title>
      <link>https://punchagan.muse-amuse.in/blog/elfeed-hook-to-fetch-full-content/</link>
      <pubDate>Sat, 19 Dec 2015 13:42:29 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/elfeed-hook-to-fetch-full-content/</guid>
      <description>&lt;p&gt;I have started to use &lt;a href=&#34;http://pinboard.in&#34;&gt;Pinboard&lt;/a&gt;&amp;rsquo;s &lt;code&gt;unread&lt;/code&gt; tag as my to-read list.  It has a&#xA;bookmark-let that works pretty well for adding stuff into my &amp;ldquo;to-read&amp;rdquo; list.  I&#xA;then catch up on this list using &lt;code&gt;elfeed&lt;/code&gt; and subscribing to the unread items&#39;&#xA;RSS feed.  The work-flow is pretty nice for adding stuff into the list, and&#xA;finding items on the list. But, when it comes to the actual reading part, the&#xA;entries in the feed don&amp;rsquo;t have the actual content I want to read, and I end up&#xA;opening the links in a browser.&lt;/p&gt;&#xA;&lt;p&gt;Inspired by a &lt;a href=&#34;https://github.com/sursh/blaggregator/pull/80#issuecomment-165849126&#34;&gt;comment from FiloSottile&lt;/a&gt;, I realized it should be pretty easy to&#xA;setup a hook that fetches the actual content to make my reading work-flow&#xA;smoother. I wrote a &lt;a href=&#34;https://github.com/punchagan/dotfiles/blob/3285e9408b91bbf5e1c78974d003be84926f9954/bin/get_article.py&#34;&gt;small script&lt;/a&gt;, using &lt;a href=&#34;https://github.com/buriy/python-readability&#34;&gt;python-readability&lt;/a&gt;, to fetch the page&#xA;content, given a URL. This script is then hooked onto &lt;code&gt;elfeed-new-entry-hook&lt;/code&gt;,&#xA;to fetch content of for new entries as they are fetched.  All the old entries&#xA;can be easily fixed with a single call to &lt;code&gt;elfeed-apply-hooks-now&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/get-url-content&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;Fetches the content for a url.&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;shell-command-to-string&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;format&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;~/bin/get_article.py %s&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/get-entry-content&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;Fetches content for pinboard entries that are not tweets.&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interactive&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;entry&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;elfeed-show-entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;     &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;list&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;url&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;elfeed-entry-link&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;feed-id&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;elfeed-deref&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;elfeed-entry-feed-id&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;content&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;elfeed-deref&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;elfeed-entry-content&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;when&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;s-matches?&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;feeds.pinboard.in/&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;feed-id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;               &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;s-matches?&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;twitter.com/\\|pdf$\\|png$\\|jpg$&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;               &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;string-equal&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;content&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pc/get-url-content&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setf&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;elfeed-entry-content&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;elfeed-ref&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;add-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;elfeed-new-entry-hook&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pc/get-entry-content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>Say Howdy with Emacs!</title>
      <link>https://punchagan.muse-amuse.in/blog/say-howdy-with-emacs/</link>
      <pubDate>Thu, 28 May 2015 00:00:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/say-howdy-with-emacs/</guid>
      <description>&lt;p&gt;Staying in touch with people is something I&amp;rsquo;m not very good at.  Since I am not&#xA;on popular (among my friends/family) networks &amp;ndash; FB and Whatsapp &amp;ndash; I don&amp;rsquo;t&#xA;even see random updates from people, to get some sense of being in touch.&lt;/p&gt;&#xA;&lt;p&gt;I recently read some old posts by Sacha Chua and was inspired by how much code&#xA;she had for &lt;a href=&#34;http://sachachua.com/blog/category/geek/emacs/bbdb/&#34;&gt;contact management&lt;/a&gt; in her old blog posts.  I was inspired by &lt;a href=&#34;http://sachachua.com/blog/2005/05/keeping-in-touch/&#34;&gt;this&#xA;post&lt;/a&gt; in particular to try and be more meticulous about how I stay in touch with&#xA;people. Michael Fogleman &lt;a href=&#34;https://mwfogleman.github.io/posts/08-01-2015-emacs-can-keep-in-touch.html&#34;&gt;blogged&lt;/a&gt; about his contact management work-flow using&#xA;&lt;code&gt;keepintouch&lt;/code&gt;. It seemed to do most of what I wanted, but I wanted this to be&#xA;integrated with my &lt;code&gt;org-contacts-db&lt;/code&gt; and I felt having native elisp code would&#xA;make it easier to hook up email, chat, etc. to this.&lt;/p&gt;&#xA;&lt;p&gt;I ended up writing a small utility called &lt;a href=&#34;https://github.com/punchagan/howdy/&#34;&gt;howdy&lt;/a&gt; to help me keep in touch with&#xA;people. It currently has only a couple of features:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;kbd&gt;M-x howdy&lt;/kbd&gt; lets me update the last contacted timestamp for a contact.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Shows me contacts that I&amp;rsquo;m out of touch in the agenda, once I add the&#xA;following snippet to an agenda file.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;​* Howdy&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  %%(howdy-howdy)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;I also have a few hooks to hook up jabber messages and email to update the db.&#xA;I&amp;rsquo;ve added them to &lt;code&gt;howdy-hooks.el&lt;/code&gt; in case anybody else wants to use them.&#xA;They can also be used as examples to write other hooks. Feel free to contribute&#xA;other hooks or suggest improvements.  The library also ships with a modest test&#xA;suite, that will hopefully make it easier for others to contribute.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;m looking forward to experimenting with this over the next few weeks and&#xA;improving it. Hopefully, it&amp;rsquo;ll help me keep in touch, better than I do now.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>org-drill for making it stick!</title>
      <link>https://punchagan.muse-amuse.in/blog/org-drill-for-making-it-stick/</link>
      <pubDate>Sat, 17 Jan 2015 00:00:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/org-drill-for-making-it-stick/</guid>
      <description>&lt;p&gt;Those who read the &lt;a href=&#34;https://punchagan.muse-amuse.in/posts/learning-to-use-org-drill.html&#34;&gt;last&lt;/a&gt; &lt;a href=&#34;https://punchagan.muse-amuse.in/posts/learning-about-spaced-repetition-supermemo-org-drill-et-al.html&#34;&gt;few&lt;/a&gt; &lt;a href=&#34;https://punchagan.muse-amuse.in/posts/more-input-sources-for-org-drill.html&#34;&gt;posts&lt;/a&gt; here, would know that I have been&#xA;experimenting with &lt;a href=&#34;http://orgmode.org/worg/org-contrib/org-drill.html&#34;&gt;org-drill&lt;/a&gt; (a spaced repetition extension to &lt;a href=&#34;http://orgmode.org/&#34;&gt;Org mode&lt;/a&gt;).  I&#xA;have been using the system (almost) religiously for the past 2 months, and I do&#xA;find that it has helped a great deal! (in some respects).  I have also spent a&#xA;considerable amount of time trying to reduce the friction to put new stuff into&#xA;the system, and am constantly on the look out for further improvements.&lt;/p&gt;&#xA;&lt;p&gt;Using this system has definitely helped with retention, and I find that I can&#xA;recall quite a few things I have read a few weeks ago, that I would normally&#xA;have been unable to. Though, I can recall a lot of information, I have been&#xA;having a feeling of &amp;ldquo;fragmentation&amp;rdquo;: the feeling of just retaining individual&#xA;bits/fragments of information, while losing out on actually internalizing the&#xA;knowledge; not seeing the big picture, etc.&lt;/p&gt;&#xA;&lt;p&gt;Wozniak (the author of super-memo) &lt;a href=&#34;http://www.supermemo.com/articles/20rules.htm&#34;&gt;warns against&lt;/a&gt; learning without&#xA;understanding, and memorizing before actually learning stuff.  I haven&amp;rsquo;t&#xA;consciously added stuff into the system that I didn&amp;rsquo;t understand (when I added&#xA;it), but, later it does feel like I have lost some connections or the&#xA;understanding, and am only holding onto the fragments of information.&lt;/p&gt;&#xA;&lt;p&gt;The problems as explained in (read: as interpreted by me from) &lt;a href=&#34;http://www.amazon.com/Make-Stick-Science-Successful-Learning/dp/0674729013/ref=sr_1_1/188-6768042-2821103?ie=UTF8&amp;amp;qid=1421439099&amp;amp;sr=8-1&amp;amp;keywords=make+it+stick&amp;amp;pebp=1421439103302&amp;amp;peasin=674729013&#34;&gt;Make it Stick&lt;/a&gt;&#xA;appear to be:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;The understanding (if any) at the time of adding stuff into the&#xA;spaced-repetition system is untested.  It may just be familiarity&#xA;masquerading as understanding.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;The lack of any spaced repetitions for the overall concept/understanding and&#xA;actual repetitions only for individual bits doesn&amp;rsquo;t help retention of the&#xA;understanding (even if there was any, in the first place).&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;To work around this, I&amp;rsquo;m going to try adding questions that test understanding,&#xA;to the system.  The Super-memo team strongly recommends keeping the drill items&#xA;small and easy to answer.  This may be helpful in keeping each drill session&#xA;short, but I would really like to add conceptual questions to the system, and&#xA;see how it goes. I hacked &lt;code&gt;org-drill&lt;/code&gt; to allow me to type out answers, before&#xA;looking at the &amp;ldquo;correct&amp;rdquo; ones.  This is an adaptation of a system that a fellow&#xA;Hacker Schooler uses, and shared.  Also, hopefully forcing myself to type out&#xA;the answer will help me get around the problem of sometimes saying &amp;ldquo;yeah I know&#xA;that&amp;rdquo;, then looking at the answer only to reaffirm the feeling of familiarity,&#xA;rather than actually testing myself.  I&amp;rsquo;m still going to continue adding quick&#xA;and short questions that test &amp;ldquo;bits of information&amp;rdquo;, though. But, hopefully the&#xA;additional conceptual questions are going to tie things together and help fill&#xA;in the gaps.  Lets see how this goes!&lt;/p&gt;&#xA;&lt;p&gt;For those interested, my hacks to &lt;code&gt;org-drill&lt;/code&gt; below.  The code is really a&#xA;hack, and welcome any suggestions on cleaning up the code.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;advice-add&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;org-drill-presentation-prompt&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;:around&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;pc/org-drill-presentation-prompt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/org-drill-presentation-prompt&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;old-fun&lt;/span&gt; &lt;span class=&#34;kp&#34;&gt;&amp;amp;rest&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;fmt-and-args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;A presentation prompt that allows capturing answers.&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;cb&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;current-buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;heading&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;nth&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-heading-components&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;entry-id&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-entry-get&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;point&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;ID&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;input&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;switch-to-buffer-other-window&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;*org-capture-drill-answer*&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;insert&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;# Hit C-c C-c once you are done answering!\n&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-insert-heading-respect-content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;insert&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;format&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Answer: %s&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;heading&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-entry-put&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;point&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;QUESTION_ID&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;entry-id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;goto-char&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;point-max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;insert&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;  &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-time-stamp-inactive&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;16&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;insert&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;\n\n  &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;input&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;equal&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;input&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;ignore-errors&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;execute-kbd-macro&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;input&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;read-key-sequence&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;switch-to-buffer-other-window&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;cb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;apply&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;old-fun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;fmt-and-args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;advice-add&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;org-drill-reschedule&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;:around&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;pc/org-drill-reschedule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/org-drill-reschedule&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;old-fun&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;Calls the original reschedule, but also archives the answer&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;prog1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;funcall&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;old-fun&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;cb&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;current-buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;switch-to-buffer-other-window&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;*org-capture-drill-answer*&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pc/org-refile-to-datetree&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;drill.org_archive&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;buffer-name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;switch-to-buffer-other-window&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;cb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;kill-buffer&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;*org-capture-drill-answer*&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;org-datetree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/org-refile-to-datetree&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;journal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;Refile an entry to journal file&amp;#39;s date-tree&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interactive&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;fRefile to: &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;let*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;journal&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expand-file-name&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;journal&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;date-string&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-entry-get&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;point&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;TIMESTAMP_IA&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                          &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-entry-get&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;point&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;TIMESTAMP&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;dct&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;decode-time&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;date-string&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-time-string-to-time&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;date-string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                               &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;current-time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;date&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;list&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;nth&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;dct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;nth&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;dct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;nth&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;dct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-cut-subtree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;with-current-buffer&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;find-buffer-visiting&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;journal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                             &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;find-file-noselect&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;journal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;save-excursion&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-datetree-file-entry-under&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-kill&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;date&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;bookmark-set&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;org-refile-last-stored&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Refiled to %s&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;journal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>Jabber message queue</title>
      <link>https://punchagan.muse-amuse.in/blog/jabber-message-queue/</link>
      <pubDate>Wed, 10 Dec 2014 00:00:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/jabber-message-queue/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve always wanted to be able to queue up messages to send to friends, until I&#xA;go online the next time.  I tried using email instead of chat a few times, or&#xA;just ended up staying online with a busy status.&lt;/p&gt;&#xA;&lt;p&gt;Finally, now that I have started using jabber-mode for chatting from within&#xA;Emacs, I took out the time to write a &amp;ldquo;queuing system&amp;rdquo; for sending chat&#xA;messages, similar to the mail queue for smtpmail.  Instead of persisting sexps,&#xA;though, I persist the messages in a JSON format and the queue is flushed every&#xA;time I connect to jabber, in a &lt;code&gt;jabber-post-connect-hook&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;To make the interface as similar to the interface available when I am online, I&#xA;hacked completion for the to ID using email addresses in my address book&#xA;(&lt;code&gt;mu4e~contact-list&lt;/code&gt;).  I really like the fact that the chat buffer opens up,&#xA;and I can type and send messages like I usually do.  Hitting &lt;kbd&gt;RET&lt;/kbd&gt; after typing&#xA;a message queues it up, instead of trying to send it. Smooth!&lt;/p&gt;&#xA;&lt;p&gt;The code is in my &lt;a href=&#34;https://github.com/punchagan/dot-emacs/blob/master/punchagan.org#jabber&#34;&gt;.emacs&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>erc-notifications when Emacs not in focus</title>
      <link>https://punchagan.muse-amuse.in/blog/erc-notifications-when-emacs-not-in-focus/</link>
      <pubDate>Thu, 06 Nov 2014 00:00:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/erc-notifications-when-emacs-not-in-focus/</guid>
      <description>&lt;p&gt;I have been trying to get ERC working with notifications. Julien Danjou&amp;rsquo;s&#xA;wonderful &lt;a href=&#34;https://julien.danjou.info/blog/2012/erc-notifications&#34;&gt;notifications&lt;/a&gt; module for ERC is great, but it is annoying to get&#xA;notifications even when Emacs is in focus.&lt;/p&gt;&#xA;&lt;p&gt;I had looked at &lt;a href=&#34;https://github.com/eqyiel/circe-notifications/blob/master/circe-notifications.el&#34;&gt;circe-notifications&lt;/a&gt;, which has the feature but uses xdotool and&#xA;xprop to do it.  I was looking for something simpler, though&amp;hellip; and it suddenly&#xA;struck me that I have an auto-save hook in Emacs that is run when I focus out&#xA;of it.  I wondered if I could disable and enable notifications on focus, and it&#xA;worked.&lt;/p&gt;&#xA;&lt;p&gt;In case it is useful for somebody else -&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;add-to-list&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;erc-modules&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;notifications&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;erc-notifications-mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;add-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;focus-out-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;erc-notifications-enable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;add-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;focus-in-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;erc-notifications-disable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I wonder if there are some corner cases where this doesn&amp;rsquo;t work, and that&amp;rsquo;s why&#xA;the author of circe-notifications chose the tools that he did.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>More input sources for org-drill</title>
      <link>https://punchagan.muse-amuse.in/blog/more-input-sources-for-org-drill/</link>
      <pubDate>Tue, 04 Nov 2014 00:00:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/more-input-sources-for-org-drill/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been trying to use &lt;code&gt;org-drill&lt;/code&gt; regularly for the last few weeks.  I don&amp;rsquo;t&#xA;know how well it&amp;rsquo;s been going but I have been sticking to the routine&#xA;religiously.  I haven&amp;rsquo;t yet really tried out incremental reading, but in an&#xA;attempt to make it as easy as possible, I wanted to have a pdf-reader&#xA;integration, and some kind of integration with Kindle highlights.  Browser&#xA;integration is pretty straight-forward, thanks to some &lt;a href=&#34;http://orgmode.org/worg/org-contrib/org-protocol.html#sec-6&#34;&gt;simple java-script&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;I looked for a pdf-reader with some sort of plugin support, but I found nothing&#xA;in Evince or Okular.  I thought about &lt;code&gt;pdfjs&lt;/code&gt; but it seemed slightly clunky to&#xA;open pdfs in a browser, though I might shift to this if I don&amp;rsquo;t like what I&#xA;finally ended up with.  Good old &lt;code&gt;xpdf&lt;/code&gt; seemed to be the only pdf reader that&#xA;had some support for custom keybindings that allowed users to run external&#xA;commands.  With a &lt;a href=&#34;https://github.com/punchagan/dot-emacs/blob/master/xpdf-capture&#34;&gt;little Python&lt;/a&gt;, I was able to setup a work-flow to capture&#xA;snippets from &lt;code&gt;xpdf&lt;/code&gt;, to add to org-drill. Custom key-bindings somehow don&amp;rsquo;t&#xA;seem to work on &lt;code&gt;xpdf&lt;/code&gt; bundled on Ubuntu. So, I ended up downloading and using&#xA;the binary available on the xpdf site.&lt;/p&gt;&#xA;&lt;p&gt;For Kindle highlights support, with minor updates to Thamer Mahmoud&amp;rsquo;s &lt;a href=&#34;https://github.com/punchagan/clip2org&#34;&gt;clip2org&lt;/a&gt;,&#xA;I have a simple way of getting all the &amp;ldquo;new&amp;rdquo; clippings/highlights as org-drill&#xA;headlines.  I haven&amp;rsquo;t really started using this, and once I do, I may end-up&#xA;automating even the merging of these items into the org-drill notes file.  I&amp;rsquo;m&#xA;looking forward to making better use of my Kindle, with this feature!&lt;/p&gt;&#xA;&lt;p&gt;I don&amp;rsquo;t know if it would be useful to have more context information like&#xA;section titles/chapter titles when capturing from html/pdf, but it seems like&#xA;an interesting problem to try to solve.&lt;/p&gt;&#xA;&lt;p&gt;Also, it might be easier(?) if I probably tried to have a DE level keybinding, and&#xA;some code to get selection and file name of the currently active&#xA;window/application.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Recurse Center, 2014-07-29</title>
      <link>https://punchagan.muse-amuse.in/recurse-center/recurse-center-2014-07-29/</link>
      <pubDate>Tue, 29 Jul 2014 11:20:24 -0400</pubDate>
      <guid>https://punchagan.muse-amuse.in/recurse-center/recurse-center-2014-07-29/</guid>
      <description>&lt;h2 id=&#34;hacking-learning-by-breaking-stuff&#34;&gt;Hacking: learning by breaking stuff&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Post lunch, I started pairing with Stephanie on the exercises in the &lt;a href=&#34;http://www.nostarch.com/hacking2.htm&#34;&gt;Hacking&lt;/a&gt;&#xA;book, and that turned out to be super fun!&lt;/li&gt;&#xA;&lt;li&gt;We got through the chapter on exploitation, which focussed on stack&#xA;overflows, heap overflows, overflows in function pointers, and string&#xA;formatting exploits.  It acted as more than a gentle refresher for C, and was&#xA;super fun!&lt;/li&gt;&#xA;&lt;li&gt;Running the examples on a 64bit system, added an additional amount of&#xA;thinking required, and was good, IMO.&lt;/li&gt;&#xA;&lt;li&gt;I hadn&amp;rsquo;t worked along with Stephanie on the material in the first two&#xA;chapters.  So, I went back home and tried to catch up, but couldn&amp;rsquo;t get all&#xA;of it done.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;miscellaneous&#34;&gt;Miscellaneous&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;I spent part of the morning wrapping up the install script for the raspberry&#xA;project, and cleaning up the repository.  &lt;a href=&#34;https://github.com/kbeyer/RPi-LED-SpectrumAnalyzer&#34;&gt;It looks reasonable now&lt;/a&gt;, and I&#xA;think I&amp;rsquo;m done with it until the end of HackerSchool.&lt;/li&gt;&#xA;&lt;li&gt;I also tried to look for &amp;ldquo;easy&amp;rdquo; python issues that would involve me writing&#xA;some C code, but didn&amp;rsquo;t really find anything other than documentation&amp;hellip; I&#xA;guess, I should pick a module and look for bugs in it, instead.&lt;/li&gt;&#xA;&lt;li&gt;Also, while chatting with a friend, I had to explain that I don&amp;rsquo;t mention the&#xA;last names of people or link to them, for privacy reasons.  Hacker School is&#xA;particularly careful about not divulging information about who are at Hacker&#xA;School each batch, and I want to keep that tradition.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</description>
    </item>
    <item>
      <title>Let there be light, in skype!</title>
      <link>https://punchagan.muse-amuse.in/blog/let-there-be-light-in-skype/</link>
      <pubDate>Sat, 29 Mar 2014 00:00:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/let-there-be-light-in-skype/</guid>
      <description>&lt;p&gt;At home, my video would always show a silhouette in G+ and Skype, and&#xA;I always thought that this was because the lighting at home was not&#xA;sufficient.  At office, the video was decent.  But, moving to sit&#xA;right under the light also didn&amp;rsquo;t help much.&lt;/p&gt;&#xA;&lt;p&gt;Struggling with a bunch of tools like &lt;code&gt;v4lctl&lt;/code&gt;, &lt;code&gt;guvcview&lt;/code&gt; didn&amp;rsquo;t&#xA;help. But, during these struggles I noticed that &lt;code&gt;cheese&lt;/code&gt; would show&#xA;me bright and cheerful, while all the other programs showed my&#xA;silhouette.&lt;/p&gt;&#xA;&lt;p&gt;I set out to &amp;ldquo;fake&amp;rdquo; the output of &lt;code&gt;cheese&lt;/code&gt; as a video device that&#xA;skype and other programs could use. But, I didn&amp;rsquo;t have to go all the&#xA;way.  I ended up using &lt;a href=&#34;https://github.com/umlaeute/v4l2loopback/&#34;&gt;v4l2loopback&lt;/a&gt; to create a loopback video device,&#xA;and just using &lt;code&gt;gst-launch&lt;/code&gt; to redirect video to that device, did the&#xA;trick!  Thanks gstreamer!  Thanks v4l2loopback! :)&lt;/p&gt;&#xA;&lt;p&gt;Here&amp;rsquo;s a convenient &lt;a href=&#34;https://gist.github.com/punchagan/9859210&#34;&gt;script&lt;/a&gt; to use it every time I need it.&lt;/p&gt;&#xA;&lt;script src=&#34;https://gist.github.com/9859210.js&#34;&gt;&lt;/script&gt;&#xA;</description>
    </item>
    <item>
      <title>Scraping Google Groups</title>
      <link>https://punchagan.muse-amuse.in/blog/scraping-google-groups/</link>
      <pubDate>Tue, 31 Dec 2013 00:00:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/scraping-google-groups/</guid>
      <description>&lt;p&gt;I was playing around with a few ideas for creating a timeline for the&#xA;mumbai ultimate group, and as a part of playing around with stuff, for&#xA;that idea, I ended up wanting to scrape all the emails on our google&#xA;group.  After looking around a little bit, I failed to find anything&#xA;that claims to be able to do this.&lt;/p&gt;&#xA;&lt;p&gt;So I ended up writing my own &lt;a href=&#34;https://gist.github.com/punchagan/7947337&#34;&gt;hacky script&lt;/a&gt; to download all the emails&#xA;sent on the group.  Like I said, this is a hack and can be improved&#xA;quite a bit, but I am not inclined to do anything about it, right&#xA;now.  Since, everything about google groups is ajaxy, this script uses&#xA;selenium and does things on the page, that one would do by hand.  It&amp;rsquo;s&#xA;not something that I am proud of, but it does the job!&lt;/p&gt;&#xA;</description>
    </item>
  </channel>
</rss>
