<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0"
xmlns:atom="
http://www.w3.org/2005/Atom"
xmlns:content="
http://purl.org/rss/1.0/modules/content/">
<channel>
<title>Amin Bandali</title>
<description>writings and talks by bandali</description>
<link>
https://kelar.org/~bandali/</link>
<language>en</language>
<lastBuildDate>Sat, 06 Dec 2025 10:50:00 -0500</lastBuildDate>
<pubDate>Sat, 06 Dec 2025 10:50:00 -0500</pubDate>
<ttl>1440</ttl>
<atom:link hreflang="fa" href="
https://kelar.org/~bandali/fa/rss20.xml" rel="alternate" type="application/rss+xml" />
<atom:link hreflang="fa" href="
gopher://kelar.org/1/~bandali/fa/" rel="alternate" type="text/plain" />
<atom:link hreflang="fa" href="
https://kelar.org/~bandali/fa/" rel="alternate" type="text/html" />
<atom:link href="
https://kelar.org/~bandali/rss20.xml" rel="self" type="application/rss+xml" />
<atom:link href="
gopher://kelar.org/1/~bandali/" rel="alternate" type="text/plain" />
<atom:link href="
https://kelar.org/~bandali/" rel="alternate" type="text/html" />
<item>
<title>Reading and writing emails in GNU Emacs with Gnus</title>
<link>
https://kelar.org/~bandali/2025/12/06/emacsconf-2025-gnus.html</link>
<atom:link href="
https://kelar.org/~bandali/2025/12/06/emacsconf-2025-gnus.html" rel="alternate" type="text/html" />
<atom:link href="
https://kelar.org/~bandali/2025/12/06/emacsconf-2025-gnus.txt" rel="alternate" type="text/plain" />
<guid isPermaLink="false">tag:kelar.org,2021:~bandali/rss20.xml:2025/12/06/emacsconf-2025-gnus</guid>
<pubDate>Sat, 06 Dec 2025 10:50:00 -0500</pubDate>
<atom:updated>2025-12-06T10:50:00-05:00</atom:updated>
<content:encoded><![CDATA[
<p>At the 10th anniversary of my involvement in EmacsConf, I’m finally
giving my first ever talk at the conference, for EmacsConf 2025. :)
In this talk, I give a quick introduction to Gnus and show a basic
configuration for reading and writing email with Gnus and Message.</p>
<p>You can watch the video below, or from the talk’s page on the
EmacsConf 2025 wiki: <a href="
https://emacsconf.org/2025/talks/gnus">
https://emacsconf.org/2025/talks/gnus</a></p>
<div><video preload="metadata" controls="controls" width="720" src="
https://archive.org/download/emacsconf-2025-gnus/emacsconf-2025-gnus.mp4" poster="
https://kelar.org/~bandali/2025/12/06/emacsconf-2025-gnus-poster.jpg">
<source src="
https://archive.org/download/emacsconf-2025-gnus/emacsconf-2025-gnus.mp4" type="video/mp4"></source>
<track label="English" kind="captions" srclang="en" src="
https://kelar.org/~bandali/2025/12/06/emacsconf-2025-gnus-captions.vtt" default=""></track>
<track kind="chapters" label="Chapters" src="
https://kelar.org/~bandali/2025/12/06/emacsconf-2025-gnus-captions-chapters.vtt"></track>
<p>Sorry, this embedded video will not work,
because your web browser does not support HTML5 video.<br>
<a href="
https://archive.org/download/emacsconf-2025-gnus/emacsconf-2025-gnus.mp4">[
please watch the video in your favourite streaming media player
]</a></p></video></div>
<p>The above video is provided with <a href="
https://kelar.org/~bandali/2025/12/06/emacsconf-2025-gnus-captions.vtt">closed captions</a> and a <a href="
https://kelar.org/~bandali/2025/12/06/emacsconf-2025-gnus-transcript.txt">transcript</a>
— thanks, Sacha!</p>
<p>A commented copy of the init file from the video is provided below.
Happy hacking!</p>
<pre><code>;;; emacsconf-2025-gnus.el -*- lexical-binding: t -*-
;; This file is marked with CC0 1.0 Universal
;; and is dedicated to the public domain.
;; Note: this file uses the `setopt' macro introduced in Emacs 29
;; to customize the value of user options. If you are using older
;; Emacsen, you may can use `customize-set-variable' or `setq'.
;;; Init / convenience
;; Initialize the package system.
(require 'package)
(package-initialize)
(setopt
;; Explicitly set `package-archives', in part to ensure https ones
;; are used, and also to have NonGNU ELPA on older Emacsen as well.
package-archives
'(("gnu" . "
https://elpa.gnu.org/packages/")
("nongnu" . "
https://elpa.nongnu.org/nongnu/")))
;; Download descriptions of available packages from the above
;; package archives.
(unless package-archive-contents
(package-refresh-contents))
;; Install the keycast package if not already installed.
(dolist (package '(keycast))
(unless (package-installed-p package)
(package-install package)))
;; Enable keycast to show the current command and its binding in
;; the mode line, for the presentation.
(setopt keycast-mode-line-remove-tail-elements nil)
(when (fboundp #'keycast-mode-line-mode)
(keycast-mode-line-mode 1))
;; Set a font with larger size for the presentation.
;; It requires that the Source Code Pro be installed on your
;; system. Feel free to comment out or remove.
(when (display-graphic-p)
(with-eval-after-load 'faces
(let ((f "Source Code Pro Medium-15"))
(set-face-attribute 'default nil :font f)
(set-face-attribute 'fixed-pitch nil :font f))))
;; Inline function for expanding file and directory names inside
;; `user-emacs-directory'. For example: (+emacs.d "gnus/")
(defsubst +emacs.d (path)
"Expand PATH relative to `user-emacs-directory'."
(expand-file-name
(convert-standard-filename path) user-emacs-directory))
(keymap-global-set "C-c e e" #'eval-last-sexp)
;; Add the info directory from the GNU Emacs source repository to
;; the list of directories to search for Info documentation files.
;; Useful if you're using Emacs directly built from a source
;; repository, rather than installed on your system.
(with-eval-after-load 'info
(setq
Info-directory-list
`(,@Info-directory-list
,(expand-file-name
(convert-standard-filename "info/") source-directory)
"/usr/share/info/")))
;;; Gnus configuration
;; (info "(gnus) Don't Panic")
(keymap-global-set "C-c g" #'gnus)
(setopt
user-full-name "Gnus Fan Emacsian"
user-mail-address "
[email protected]")
;; Tell Emacs we'd like to use Gnus and its Message integration
;; for reading and writing mail.
(setopt
mail-user-agent 'gnus-user-agent
read-mail-command #'gnus)
;; Consolidate various Gnus files inside a gnus directory in the
;; `user-emacs-directory'.
(setopt
gnus-home-directory (+emacs.d "gnus/")
gnus-directory (+emacs.d "gnus/news/")
message-directory (+emacs.d "gnus/mail/")
nndraft-directory (+emacs.d "gnus/drafts/"))
(setopt ; don't bother with .newsrc, use .newsrc.eld instead
gnus-save-newsrc-file nil
gnus-read-newsrc-file nil)
;; Don't prompt for confirmation when exiting Gnus.
(setopt gnus-interactive-exit nil)
;; Configure two IMAP mail accounts.
(setopt
gnus-select-method '(nnnil "")
gnus-secondary-select-methods
'((nnimap
"ec25gnus"
(nnimap-stream tls)
(nnimap-address "mail.kelar.org")
;; (nnimap-server-port 993) ; imaps
(nnimap-authenticator plain)
(nnimap-user "
[email protected]"))
(nnimap
"ec25work"
(nnimap-stream tls)
(nnimap-address "mail.kelar.org")
;; (nnimap-server-port 993) ; imaps
(nnimap-authenticator plain)
(nnimap-user "
[email protected]")
;; Archive messages into yearly Archive folders upon pressing
;; 'E' (for Expire) in the summary buffer.
(nnmail-expiry-wait immediate)
(nnmail-expiry-target nnmail-fancy-expiry-target)
(nnmail-fancy-expiry-targets
(("from" ".*" "nnimap+ec25work:Archive.%Y"))))))
;; `init-file-debug' corresponds to launching emacs with --debug-init
(setq nnimap-record-commands init-file-debug)
;; The "Sent" folder
(setopt gnus-message-archive-group "nnimap+ec25gnus:INBOX")
;;;; Group buffer
;; Always show INBOX groups even if they have no unread or ticked
;; messages.
(setopt gnus-permanently-visible-groups ":INBOX$")
;; Enable topic mode in the group buffer, for classifying groups.
(add-hook 'gnus-group-mode-hook #'gnus-topic-mode)
;;;; Article buffer
;; Display the following message headers in Article buffers,
;; in the given order.
(setopt
gnus-sorted-header-list
'("^From:"
"^X-RT-Originator"
"^Newsgroups:"
"^Subject:"
"^Date:"
"^Envelope-To:"
"^Followup-To:"
"^Reply-To:"
"^Organization:"
"^Summary:"
"^Abstract:"
"^Keywords:"
"^To:"
"^[BGF]?Cc:"
"^Posted-To:"
"^Mail-Copies-To:"
"^Mail-Followup-To:"
"^Apparently-To:"
"^Resent-From:"
"^User-Agent:"
"^X-detected-operating-system:"
"^X-Spam_action:"
"^X-Spam_bar:"
"^Message-ID:"
;; "^References:"
"^List-Id:"
"^Gnus-Warning:"))
;;;; Summary buffer
;; Fine-tune sorting of threads in the summary buffer.
;; See: (info "(gnus) Sorting the Summary Buffer")
(setopt
gnus-thread-sort-functions
'(gnus-thread-sort-by-number
gnus-thread-sort-by-subject
gnus-thread-sort-by-date))
;;;; Message and sending mail
(setopt
;; Automatically mark Gcc (sent) messages as read.
gnus-gcc-mark-as-read t
;; Configure posting styles for per-account Gcc groups, and SMTP
;; server for sending mail. See: (info "(gnus) Posting Styles")
;; Also see sample .authinfo file provided below.
gnus-posting-styles
'(("nnimap\\+ec25gnus:.*"
(address "
[email protected]")
("X-Message-SMTP-Method" "smtp mail.kelar.org 587")
(gcc "nnimap+ec25gnus:INBOX"))
("nnimap\\+ec25work:.*"
(address "
[email protected]")
("X-Message-SMTP-Method" "smtp dasht.kelar.org 587")
(gcc "nnimap+ec25work:INBOX"))))
(setopt
;; Ask for confirmation when sending a message.
message-confirm-send t
;; Wrap messages at 70 characters when pressing M-q or when
;; auto-fill-mode is enabled.
message-fill-column 70
;; Forward messages (C-c C-f) as a proper MIME part.
message-forward-as-mime t
;; Send mail using Emacs's built-in smtpmail library.
message-send-mail-function #'smtpmail-send-it
;; Omit our own email address(es) when composing replies.
message-dont-reply-to-names "ec25\\(gnus\\|work\\)@kelar\\.org"
gnus-ignored-from-addresses message-dont-reply-to-names)
;; Unbind C-c C-s for sending mail; too easy to accidentally hit
;; instead of C-c C-d (save draft for later)
(keymap-set message-mode-map "C-c C-s" nil)
;; Display a `fill-column' indicator in Message mode.
(add-hook 'message-mode-hook #'display-fill-column-indicator-mode)
;; Enable Flyspell for on-the-fly spell checking.
(add-hook 'message-mode-hook #'flyspell-mode)
</code></pre>
<p>Sample <code>~/.authinfo</code> file:</p>
<pre><code>machine ec25gnus login
[email protected] password hunter2
machine ec25work login
[email protected] password badpass123
machine mail.kelar.org login
[email protected] password hunter2
machine dasht.kelar.org login
[email protected] password badpass123
</code></pre>
<p>Note that for purpose of storing credentials for use by Gnus’s select
methods, the <code>machine</code> portions need to match the names we give our
select methods when configuring <code>gnus-secondary-select-methods</code>,
namely <code>ec25gnus</code> and <code>ec25work</code> in our example.</p>
<p>We also store a copy of the credentials for use by Emacs’s smtpmail
when sending mail, where the <code>machine</code> must be the fully-qualified
domain name (FQDN) of the SMTP server we specify with the
<code>X-Message-SMTP-Method</code> header for each account by defining a
corresponding rule for it in <code>gnus-posting-styles</code>.</p>
<p>Lastly, I recommend using an encrypted authinfo file by saving it as
<code>~/.authinfo.gpg</code> instead to avoid storing your credentials in plain
text. If you set up Emacs’s EasyPG, it will seamlessly decrypt or
encrypt the file using GPG when reading from or writing to it.
Type <code>C-h v auth-sources RET</code> to see the documentation of the
<code>auth-sources</code> variable for more details.</p>
]]></content:encoded></item>
<item>
<title>Free software activities in November 2025</title>
<link>
https://kelar.org/~bandali/2025/11/30/fsa.html</link>
<atom:link href="
https://kelar.org/~bandali/2025/11/30/fsa.html" rel="alternate" type="text/html" />
<atom:link href="
https://kelar.org/~bandali/2025/11/30/fsa.txt" rel="alternate" type="text/plain" />
<guid isPermaLink="false">tag:kelar.org,2021:~bandali/rss20.xml:2025/11/30/fsa</guid>
<pubDate>Sun, 30 Nov 2025 18:26:46 -0500</pubDate>
<atom:updated>2025-11-30T18:26:46-05:00</atom:updated>
<content:encoded><![CDATA[
<p>Hello and welcome to my November free software activities report.
I’ve been working on a number of things throughout this month but
they’re not quite ready for reporting yet, so this month’s report
will be quite short.</p>
<h2 id="gnu-fsf">GNU & FSF</h2>
<ul>
<li><p><a href="
https://emacsconf.org">EmacsConf</a>: I recorded the video for my Gnus talk for this year’s
conference. The video will be available along with the the other
EmacsConf talks from the conference website, but if you’re feeling
particularly impatient you can sneak a peek at it. :)</p>
<p><a href="
https://archive.org/details/emacsconf-2025-gnus">
https://archive.org/details/emacsconf-2025-gnus</a></p></li>
<li><p><a href="
https://www.gnu.org/spotlight/spotlight.html">GNU Spotlight</a>: I prepared and sent the November GNU Spotlight to
the FSF campaigns team for publication on the FSF’s community blog
and the monthly Free Software Supporter newsletter.</p></li>
</ul>
<p>Take care, and so long for now.</p>
]]></content:encoded></item>
<item>
<title>Free software activities in October 2025</title>
<link>
https://kelar.org/~bandali/2025/10/31/fsa.html</link>
<atom:link href="
https://kelar.org/~bandali/2025/10/31/fsa.html" rel="alternate" type="text/html" />
<atom:link href="
https://kelar.org/~bandali/2025/10/31/fsa.txt" rel="alternate" type="text/plain" />
<guid isPermaLink="false">tag:kelar.org,2021:~bandali/rss20.xml:2025/10/31/fsa</guid>
<pubDate>Fri, 31 Oct 2025 19:44:11 -0400</pubDate>
<atom:updated>2025-10-31T19:44:11-04:00</atom:updated>
<content:encoded><![CDATA[
<p>Hello and welcome to my October free software activities report.</p>
<h2 id="gnu-fsf">GNU & FSF</h2>
<ul>
<li><p><a href="
https://www.gnu.org/spotlight/spotlight.html">GNU Spotlight</a>: I prepared and sent the October GNU Spotlight
to the FSF campaigns team, who will review and publish it on the
FSF’s community blog and as part of the next issue of the monthly
Free Software Supporter newsletter.</p></li>
<li><p><a href="
https://www.gnu.org/software/emacs/">GNU Emacs</a>:</p>
<ul>
<li><p><a href="
https://bugs.gnu.org/79629">bug#79629</a>: I noticed that I was unable to customize the
<code>holiday-other-holidays</code> variable using the <code>setopt</code> macro:
my change did not seem to take effect. As Eli Zaretskii
helpfully pointed out, this was because customizing
<code>holiday-other-holidays</code> did not recompute the value of
<code>calendar-holidays</code>, which is computed once, when the package
is loaded.</p>
<p>So I prepared and sent a patch <a href="
https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=500a2d0cc55340eb3830f8a7ad49183c4b57c87c"><code>500a2d0cc55</code></a> to recompute
<code>calendar-holidays</code> when its components are set.</p></li>
<li><p><a href="
https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=bbabc1db25835fe52ff9d29c1689c88e82146a8a"><code>bbabc1db258</code></a>: While reading about <code>custom-reevaluate-setting</code>
in the Startup Summary node of the GNU Emacs Lisp reference manual
I noticed a small typo, so I committed a patch to fix it.</p></li>
</ul></li>
</ul>
<h2 id="misc">Misc</h2>
<ul>
<li><p>The Free Software Foundation <a href="
https://www.fsf.org/fsf40">celebrated its fortieth birthday</a>
on 4 October 2025 online and in person in Boston! I was not
able to attend the event in person, so I recorded a <a href="
https://kelar.org/~bandali/2025/10/04/fsf40-volunteer-panel.html">video for
the FSF40 volunteer panel</a> held at the venue.</p></li>
<li><p>This month at work one of our Elasticsearch clusters experienced
partial failure, and we needed to extract document IDs from a backup
of one of the cluster’s shards. Elasticsearch uses Lucene under the
hood and each shard is a standalone Lucene index, so I used Lucene’s
Java API to write a little <a href="
https://kelar.org/~bandali/software/misc/GetIDS.java"><code>GetIDS</code></a> class to query the index for
all of its documents, and for each document print its <code>_id</code> field,
decoding the binary-valued <code>BytesRef</code> as needed. The gotcha was
that all of the <code>BytesRef</code>s seemed to have a <code>-1</code> byte in the
beginning, throwing off the recommended <code>BytesRef.utf8ToString()</code>
method, so I had to reimplement that method’s logic in my program
and have it use an adjusted <code>offset + 1</code> and <code>length - 1</code> instead.</p></li>
</ul>
<p>That’s about it for this month’s report.</p>
<p>Take care, and so long for now.</p>
]]></content:encoded></item>
<item>
<title>FSF40 volunteer panel</title>
<link>
https://kelar.org/~bandali/2025/10/04/fsf40-volunteer-panel.html</link>
<atom:link href="
https://kelar.org/~bandali/2025/10/04/fsf40-volunteer-panel.html" rel="alternate" type="text/html" />
<atom:link href="
https://kelar.org/~bandali/2025/10/04/fsf40-volunteer-panel.txt" rel="alternate" type="text/plain" />
<guid isPermaLink="false">tag:kelar.org,2021:~bandali/rss20.xml:2025/10/04/fsf40-volunteer-panel</guid>
<pubDate>Sat, 04 Oct 2025 19:44:11 -0400</pubDate>
<atom:updated>2025-10-04T19:44:11-04:00</atom:updated>
<content:encoded><![CDATA[
<p><a href="
https://static.fsf.org/nosvn/fsf40/FSF40-logo.png"><img src="
https://kelar.org/~bandali/2025/10/04/fsf40-logo-sm.png" alt="Celebrate 40 years of FSF!" class="float-right" width="144"></a></p>
<p>The Free Software Foundation celebrated its fortieth birthday today
online and in person in Boston. Forty years of commitment to
software freedom and fighting for the freedoms of all computer users.</p>
<p>As part of the <a href="
https://www.fsf.org/fsf40">FSF40 celebration</a>, the FSF held a roundtable panel
with FSF volunteers both in-person and online. I was not able to
attend the event in person, so I prepared a video recording for the
volunteer roundtable that was played at the venue. In the video
I talk about my free software journey and how I first got involved,
some of the issues facing the world of free software today, and how
you can get involved and contribute to free software projects and
help the free software movement.</p>
<div><video preload="metadata" controls="controls" width="720" src="
https://archive.org/download/fsf40-volunteer-panel-bandali/fsf40-volunteer-panel-bandali.ia.mp4" poster="
https://kelar.org/~bandali/2025/10/04/fsf40-volunteer-panel-poster.jpg">
<source src="
https://archive.org/download/fsf40-volunteer-panel-bandali/fsf40-volunteer-panel-bandali.ia.mp4" type="video/mp4">
<p>Sorry, this embedded video will not work,
because your web browser does not support HTML5 video.<br>
<a href="
https://archive.org/download/fsf40-volunteer-panel-bandali/fsf40-volunteer-panel-bandali.ia.mp4">[
please watch the video in your favourite streaming media player
]</a></p></source></video></div>
<p>Happy 40th birthday, FSF, and here’s to 40+ more years of software
freedom. Happy hacking!</p>
<p>The video recording is Copyright © 2025 Amin Bandali, and is
licensed under <a href="
https://kelar.org/~bandali/license.html#cc-by-sa">CC BY-SA 4.0</a>.</p>
]]></content:encoded></item>
<item>
<title>Free software activities in September 2025</title>
<link>
https://kelar.org/~bandali/2025/09/30/fsa.html</link>
<atom:link href="
https://kelar.org/~bandali/2025/09/30/fsa.html" rel="alternate" type="text/html" />
<atom:link href="
https://kelar.org/~bandali/2025/09/30/fsa.txt" rel="alternate" type="text/plain" />
<guid isPermaLink="false">tag:kelar.org,2021:~bandali/rss20.xml:2025/09/30/fsa</guid>
<pubDate>Tue, 30 Sep 2025 19:44:11 -0400</pubDate>
<atom:updated>2025-09-30T19:44:11-04:00</atom:updated>
<content:encoded><![CDATA[
<p>Summer has been winding down here in southern Ontario and beautiful
fall colours have been slowly appearing around us, and with that, it’s
time for my September free software activities report — albeit a
very short one, as it turned out to be a busy month and I had few
free software contributions.</p>
<h2 id="gnu-fsf">GNU & FSF</h2>
<ul>
<li><a href="
https://www.gnu.org/spotlight/spotlight.html">GNU Spotlight</a>: I prepared and sent the September GNU Spotlight
to the FSF campaigns team, who will review and publish it on the
FSF’s community blog and as part of the next issue of the monthly
Free Software Supporter newsletter.</li>
</ul>
<h2 id="debian">Debian</h2>
<ul>
<li>recutils: Last month, I adopted the recutils package in Debian, and
uploaded version <code>1.9-4</code> to unstable to fix FTBFS bug <a href="
https://bugs.debian.org/1066370">#1066370</a>.
Today, I uploaded <code>1.9-4~bpo13+1</code> to trixie-backports to provide
an easy way for users of Debian 13 (Trixie) to install recutils.
The upload is currently in the backports NEW queue pending review
by the backports team, and will appear in the archive if approved.</li>
</ul>
<h2 id="misc">Misc</h2>
<ul>
<li>I had a <a href="
https://kelar.org/~bandali/2025/09/03/prot-asks.html">lovely chat with Prot</a> earlier this month for his ‘Prot
Asks’ series, where we talked about free software, free knowledge,
the importance of community and the commons, and life in Canada.</li>
</ul>
<p>That’s about it for this month’s report.
I hope to have more to share next month.</p>
<p>Take care, and so long for now.</p>
]]></content:encoded></item>
<item>
<title>Prot Asks me about EmacsConf, Debian, GNU, Internet Archive, and Canada</title>
<link>
https://kelar.org/~bandali/2025/09/03/prot-asks.html</link>
<atom:link href="
https://kelar.org/~bandali/2025/09/03/prot-asks.html" rel="alternate" type="text/html" />
<atom:link href="
https://kelar.org/~bandali/2025/09/03/prot-asks.txt" rel="alternate" type="text/plain" />
<guid isPermaLink="false">tag:kelar.org,2021:~bandali/rss20.xml:2025/09/03/prot-asks</guid>
<pubDate>Wed, 03 Sep 2025 18:58:58 -0400</pubDate>
<atom:updated>2025-09-03T18:58:58-04:00</atom:updated>
<content:encoded><![CDATA[
<p>Earlier today I joined Prot for an episode of his <a href="
https://protesilaos.com/prot-asks/">Prot Asks</a> series,
where he talks to folks about Emacs and life in general. We talked
about free software, free knowledge, the importance of community and
the commons, and life in Canada.</p>
<p>See <a href="
https://protesilaos.com/codelog/2025-09-03-prot-asks-amin-emacsconf-gnu-debian-internet-archive-canada/">the episode’s page on Prot’s website</a> for the video recording,
Prot’s summary of our chat, and the links I shared after our call.
You can also watch the recording embedded below.</p>
<div><video preload="metadata" controls="controls" width="720" src="
https://archive.org/download/prot-codelog-2025-09-03-prot-asks-amin-emacsconf-gnu-debian-internet-archive-canada/prot-codelog-2025-09-03-prot-asks-amin-emacsconf-gnu-debian-internet-archive-canada-kbJ3i3QMozs.mp4" poster="
https://kelar.org/~bandali/2025/09/03/prot-asks-poster.webp">
<source src="
https://archive.org/download/prot-codelog-2025-09-03-prot-asks-amin-emacsconf-gnu-debian-internet-archive-canada/prot-codelog-2025-09-03-prot-asks-amin-emacsconf-gnu-debian-internet-archive-canada-kbJ3i3QMozs.mp4" type="video/mp4">
<p>Sorry, this embedded video will not work,
because your web browser does not support HTML5 video.<br>
<a href="
https://archive.org/download/prot-codelog-2025-09-03-prot-asks-amin-emacsconf-gnu-debian-internet-archive-canada/prot-codelog-2025-09-03-prot-asks-amin-emacsconf-gnu-debian-internet-archive-canada-kbJ3i3QMozs.mp4">[
please watch the video in your favourite streaming media player
]</a></p></source></video></div>
<p>I really enjoyed our chat today and time went by very quickly.
Thanks again for having me, Prot!</p>
<p>Take care, and so long for now.</p>
<p>The video recording is
Copyright © 2025 Protesilaos Stavrou and Amin Bandali,
and is licensed under <a href="
https://kelar.org/~bandali/license.html#cc-by-sa">CC BY-SA 4.0</a>.</p>
]]></content:encoded></item>
<item>
<title>Free software activities in August 2025</title>
<link>
https://kelar.org/~bandali/2025/08/31/fsa.html</link>
<atom:link href="
https://kelar.org/~bandali/2025/08/31/fsa.html" rel="alternate" type="text/html" />
<atom:link href="
https://kelar.org/~bandali/2025/08/31/fsa.txt" rel="alternate" type="text/plain" />
<guid isPermaLink="false">tag:kelar.org,2021:~bandali/rss20.xml:2025/08/31/fsa</guid>
<pubDate>Sun, 31 Aug 2025 19:44:11 -0400</pubDate>
<atom:updated>2025-08-31T19:44:11-04:00</atom:updated>
<content:encoded><![CDATA[
<p>Welcome to my first free software activities report, a monthly series
in which I aim to summarize my activities in the free software
projects and communities I participate in.</p>
<h2 id="gnu-fsf">GNU & FSF</h2>
<ul>
<li>EmacsConf: I submitted a proposal to talk about <a href="
https://kelar.org/~bandali/2025/08/31/emacsconf-2025-gnus-proposal.txt">reading and writing
emails in GNU Emacs with Gnus</a> for EmacsConf 2025. This year marks
the 10th anniversary of my involvement in EmacsConf, but I’ve yet to
give a talk at the conference, so I thought it would be nice to try
and change that. I’m happy that my proposed talk has been accepted
by my fellow organizers and volunteers who review the proposals.</li>
</ul>
<!-- - maintainers@ -->
<ul>
<li>GNU Spotlight: I prepared and sent the August edition of the monthly
GNU Spotlight to the FSF campaigns team, who will review and publish
it on the FSF’s community blog and as part of the next issue of the
monthly Free Software Supporter newsletter.</li>
</ul>
<h2 id="debian">Debian</h2>
<ul>
<li><p><a href="
https://bugs.debian.org/1070268" title="ITA: recutils -- text-based databases called recfiles">#1070268</a>: I recently noticed that the recutils package is missing
in the latest release of Debian, Trixie. Indeed, recutils’ page on
the tracker shows that it was removed from testing last year due to
FTBFS bug <a href="
https://bugs.debian.org/1066370">#1066370</a>, and its maintainer requested it be adopted by
someone else in this bug. This is unfortunate, because there are
other pieces of software (including other GNU packages) that rely on
recutils, and the GNU Project also uses recutils extensively for
various record-keeping purposes.</p>
<p>So I reached out to the package’s former maintainer Sven Wick, who
gave their kind blessing for me to adopt it. I’ve adopted recutils
in Debian with an upload that also addresses the FTBFS bug.</p>
<p>Many thanks, Sven, for your years of work packaging and maintaining
recutils in Debian!</p></li>
<li><p><a href="
https://bugs.debian.org/1066370">#1066370</a>: Fixed FTBFS bug in recutils and uploaded to unstable.</p></li>
</ul>
<h2 id="devuan">Devuan</h2>
<ul>
<li><a href="
https://git.devuan.org/devuan/documentation/pulls/13">devuan/documentation#13</a>: Prepared screenshots of the installation
steps for use in the upcoming Excalibur release’s installation
guide.</li>
</ul>
<h2 id="misc">Misc</h2>
<ul>
<li>doric-themes: I contributed a tiny patch (<a href="
https://github.com/protesilaos/doric-themes/commit/cea178c9f15454acf1cc022b0e9020fb24d61d2d"><code>cea178c</code></a>) to tweak the
appearance of the <code>diary</code> and <code>org-agenda-diary</code> faces to make them
stand out more.</li>
</ul>
]]></content:encoded></item>
<item>
<title>Lispy Gopher Climate with screwlisp</title>
<link>
https://kelar.org/~bandali/2025/08/20/lispy-gopher-climate.html</link>
<atom:link href="
https://kelar.org/~bandali/2025/08/20/lispy-gopher-climate.html" rel="alternate" type="text/html" />
<atom:link href="
https://kelar.org/~bandali/2025/08/20/lispy-gopher-climate.txt" rel="alternate" type="text/plain" />
<guid isPermaLink="false">tag:kelar.org,2021:~bandali/rss20.xml:2025/08/20/lispy-gopher-climate</guid>
<pubDate>Wed, 20 Aug 2025 23:14:36 -0400</pubDate>
<atom:updated>2025-08-20T23:14:36-04:00</atom:updated>
<content:encoded><![CDATA[
<p>Last night I appeared on <a href="
https://screwlisp.small-web.org">screwlisp</a>’s live show <a href="
https://communitymedia.video/c/screwtape_channel/videos">Lispy Gopher
Climate</a> on <a href="
https://anonradio.net">aNONradio</a>. It was a fun hour chatting with screwlisp
about Emacs, EmacsConf, computing science, free software, and
community, with lively audience participation on <a href="
https://lambda.moo.mud.org">LambdaMOO</a> and
<a href="ircs://irc.libera.chat:6697/emacsconf">#emacsconf</a> IRC.</p>
<p>You can listen to the recording of the show below, or on <a href="
https://communitymedia.video/w/tPo3DYdNFT35VKo69egtBL">screwlisp’s
PeerTube</a>.</p>
<div><video preload="metadata" controls="controls" width="720" src="
https://archive.org/download/lispy-gopher-climate-2025-08-20/lispy-gopher-climate-2025-08-20.mp4" poster="
https://kelar.org/~bandali/2025/08/20/lispy-gopher-climate-poster.jpg">
<source src="
https://archive.org/download/lispy-gopher-climate-2025-08-20/lispy-gopher-climate-2025-08-20.mp4" type="video/mp4">
<p>Sorry, this embedded video will not work,
because your web browser does not support HTML5 video.<br>
<a href="
https://archive.org/download/lispy-gopher-climate-2025-08-20/lispy-gopher-climate-2025-08-20.mp4">[
please watch the video in your favourite streaming media player
]</a></p></source></video></div>
<p>Thanks, screwlisp, for having me! I had a great time on the show and
hope to be back on again at some point with more like-minded friends
like <a href="
https://corwin.bru.st">Corwin</a> to chat more about Emacs and community.</p>
<p>Take care, and so long for now.</p>
<p>The audio recording is
Copyright © 2025 screwlisp and Amin Bandali,
and is licensed under <a href="
https://kelar.org/~bandali/license.html#cc-by-sa">CC BY-SA 4.0</a>.</p>
]]></content:encoded></item>
<item>
<title>Mirroring Protesilaos' videos to Internet Archive</title>
<link>
https://kelar.org/~bandali/2025/07/25/protesilaos-videos-archive.html</link>
<atom:link href="
https://kelar.org/~bandali/2025/07/25/protesilaos-videos-archive.html" rel="alternate" type="text/html" />
<atom:link href="
https://kelar.org/~bandali/2025/07/25/protesilaos-videos-archive.txt" rel="alternate" type="text/plain" />
<guid isPermaLink="false">tag:kelar.org,2021:~bandali/rss20.xml:2025/07/25/protesilaos-videos-archive</guid>
<pubDate>Fri, 25 Jul 2025 14:02:37 -0400</pubDate>
<atom:updated>2025-07-25T14:02:37-04:00</atom:updated>
<content:encoded><![CDATA[
<p>I enjoy reading and watching the writings and videos that
<a href="
https://protesilaos.com">Protesilaos</a> publishes on his website, with his work ranging from
philosophy and various life issues to GNU Emacs and programming.
Currently, Prot uploads his videos to YouTube and embeds them on his
website. YouTube, diligently working their way down the spiral of
<a href="
https://en.wikipedia.org/wiki/Enshittification">enshittification</a>, have been making it increasingly difficult to
watch the videos without using their nonfree JavaScript interface
or their nonfree mobile applications. This got me thinking about
mirroring Prot’s videos to the Internet Archive to make them more
easily accessible in freedom.</p>
<p>To mirror all of Prot’s videos to the Internet Archive is a nontrivial
task: as of the time of this writing, there are a total of 298 videos
uploaded to Prot’s YouTube channel. Thankfully, Prot makes publicly
available the git repository containing the sources used to build his
website, and we have several excellent tools at our disposal to help
extract the information we need and carry this out.</p>
<p><strong>Note:</strong> Prot <a href="
https://protesilaos.com/license/">publishes</a> his works under free/libre copyleft
licenses like CC BY-SA 4.0 and GPLv3+, so we do not violate his
copyright by sharing or redistributing his work so long as we do it
with proper credit, following the terms of the licenses.</p>
<p>The idea is to write a program that would walk through the set of
markdown files in the source repository for Prot’s website and for
each file that has a <code>mediaid</code> metadata field, download the video
with that ID from YouTube using <code>yt-dlp</code>, and upload it along with
accompanying metadata to the Internet Archive using the
<code>internetarchive</code> Python module. Given that these two key tools are
written in Python, I opted to use Python for my own implementation
as well. (I initially started the implementation as a POSIX shell
script, but then decided that I would like the convenience of a
‘proper programming language’ and being able to interact with these
tools through their respective API, so I ported what I had to Python
and continued there.)</p>
<p>The full implementation is available at
<a href="
https://kelar.org/~bandali/2025/07/25/protesilaos_videos_archive.py">protesilaos_videos_archive.py</a>. Note that some of the required
modules are not part of Python’s standard library, namely <code>markdown</code>,
<code>yt-dlp</code>, and <code>internetarchive</code>. You can install these using your
distribution’s package manager or using <code>pip</code>, the Python package
manager.</p>
<p>The script takes several command line arguments. There is a required
positional argument for specifying the directory to search through
(recursively) for markdown files. Normally, this would be the path
to your local copy of the source repository for Prot’s website.
There are also two <code>--cookie-file</code> and <code>--working-dir</code> options for
optionally specifying the path to a cookie file for use with yt-dlp
and the working directory for storing the downloaded videos and the
progress file, respectively. Considering YouTube’s somewhat
aggressive rate-limiting of IPs, if you will be downloading a
nontrivial number of videos, you will probably want to use
<code>--cookie-file</code> to specify the file that contains cookies from a
YouTube session. (You would log into YouTube using your account,
then use an add-on like <a href="
https://addons.mozilla.org/en-US/firefox/addon/cookies-txt/">cookies.txt</a> to extract and save your
session’s cookies into a text file.)</p>
<p>Example invocation of the program:</p>
<pre><code>./protesilaos_videos_archive.py --cookie-file=cf.txt ~/src/protesilaos.gitlab.io
</code></pre>
<p>Also, considering the large number of videos to be downloaded and
uploaded, making this a long-running task, I thought it would be
helpful to allow interrupting the work partway through by stopping
the program by pressing <code>Ctrl-c</code> in the terminal to send a SIGINT.
Upon receiving a SIGINT, the program will stop the work after the
current download or upload is finished, and write the progress to
a progress file, <code>.pva-progress.jsonl</code>, which it will use on the
next run to resume the work where it was left off.</p>
<p>As of the time of this writing, all of the videos published by Prot
on his YouTube channel have been mirrored to the Internet Archive, and
are available from the <a href="
https://archive.org/details/protesilaos-videos?sort=-date">Video Publications by Protesilaos Stavrou</a>
collection.</p>
<p>I’ll wrap up by thanking Prot for clarifying the license of his
video publications and for his blessing for me to mirror them on
the Internet Archive. Thanks, Prot. :)</p>
<p>Take care, and so long for now.</p>
<p>P.S. yt-dlp has a <code>--write-description</code> option, which causes it to
write a <code>.description</code> file along with the downloaded video containing
its description text from YouTube. I still opted to go with the above
approach of using each post’s body text as ‘description’ in part
because the markdown source file for each video post contains more
metadata fields that I was planning on uploading to the Archive
anyway.</p>
]]></content:encoded></item>
<item>
<title>Don't "buy" e-books from Oxford University Press</title>
<link>
https://kelar.org/~bandali/2025/05/20/no-oup.html</link>
<atom:link href="
https://kelar.org/~bandali/2025/05/20/no-oup.html" rel="alternate" type="text/html" />
<atom:link href="
https://kelar.org/~bandali/2025/05/20/no-oup.txt" rel="alternate" type="text/plain" />
<guid isPermaLink="false">tag:kelar.org,2021:~bandali/rss20.xml:2025/05/20/no-oup</guid>
<pubDate>Tue, 20 May 2025 19:34:49 -0400</pubDate>
<atom:updated>2025-05-20T19:34:49-04:00</atom:updated>
<content:encoded><![CDATA[
<p>Last month I watched the book talk <a href="
https://blog.archive.org/event/book-talk-music-copyright-creativity-and-culture/">Music Copyright, Creativity,
and Culture</a> by Jennifer Jenkins with James Boyle facilitating
the discussion, co-hosted by the Internet Archive and the Authors
Alliance:</p>
<div class="text-center"><iframe width="560" height="316" frameborder="0" allowfullscreen="true" src="
https://archive.org/embed/music-copyright-creativity-and-culture"></iframe><br><a class="sm" href="
https://archive.org/embed/music-copyright-creativity-and-culture">Music
Copyright, Creativity, and Culture - Jennifer Jenkins</a></div>
<p>Looking to get a copy of the book, I found the book’s page on the
publisher’s website, Oxford University Press. Seeing it available as
an e-book, I opted to go with that as a more eco-friendly option and
to save some physical space. I worked my way through the checkout and
payment steps, under the impression that I would be purchasing a copy
of the book that I could download and do with as I wished. The use
of the words “buy” and “purchase” throughout the book page on the
publisher’s website certainly did not suggest otherwise.</p>
<p><a href="
https://kelar.org/~bandali/2025/05/20/oup-screenshot-2025-05-18.png"><img src="
https://kelar.org/~bandali/2025/05/20/oup-screenshot-2025-05-18-sm.png" alt="Screenshot from book page on OUP" width="920" title="Screenshot from book page on OUP"></a></p>
<p>In hindsight, there were red flags I failed to notice at the time,
such as confusing and seemingly redundant, if not contradictory,
information on the book page:</p>
<blockquote>
<p>“Downloaded copy on your device does not expire.”</p>
</blockquote>
<p>Um, okay? I’d sure hope and expect as much about any file I download.</p>
<blockquote>
<p>“Includes 4 years of Bookshelf Online.”</p>
</blockquote>
<p>Whatever — as long as I could download, store, and use the book
offline I’d be happy.</p>
<p>It’s only upon hovering the small and generic, if not misleading,
“E-book purchasing help” link that one would be presented with this
vaguely informative eyebrow-raising sentence:</p>
<blockquote>
<p><strong>E-book purchase</strong></p>
<p>E-books are granted under the terms of a single-user,
non-transferable license, and may be accessed online from any
location.</p>
</blockquote>
<p>“E-books are granted” (??) is news to me. I thought I would have
rightful access to something I bought and paid for, rather than being
“granted” (read “allowed”) access to it by and through some overlord.
Oh but of course, we live in a time where vendors get to redefine
well-established words like “purchase” and “buy” on page N of their
terms and conditions.</p>
<p>I obviously did not see that “E-book purchasing help” before giving
Oxford University Press my money: being a tech-savvy person, I didn’t
think I needed any help “purchasing” an e-book.</p>
<p>Everything became clear shortly after I completed the “purchase” and
was redirected to VitalSource to access the book: the VitalSource
“Bookshelf” user interface offered no way to download a copy of the
book I thought I bought and paid for. It is instead a glorified pile
of proprietary JavaScript DRM (<a href="
https://www.defectivebydesign.org/what_is_drm">Digital Restrictions Management</a>)
that wraps around the underlying representation of the book in
VitalSource’s possession. The only other option for accessing the
book would be through VitalSource’s proprietary application available
only for certain versions of certain proprietary operating systems.</p>
<p>At this point, the only method I could think of to try and obtain a
copy of the book that I could read without subjecting myself to the
shackles of DRM or proprietary software was trying to <em>print</em> the
book to PDF. Given that VitalSource’s DRM interface is a proprietary
wrapper around VitalSource’s likely ePub-based underlying
representation (guessing from the presence of <code>epubcfi</code> in the URL of
their book renderer page), the book pages are not exposed all at once,
practically forcing one to use the interface’s Print function to get
all the pages in one go. After waiting what felt like an eternity
for the website to prepare a printable version of the book, I was
presented with this abomination (click image for sample in original
PDF form):</p>
<p><a href="
https://kelar.org/~bandali/2025/05/20/vitalsource-print-sample.pdf"><img src="
https://kelar.org/~bandali/2025/05/20/vitalsource-print-sample.jpg" alt="Sample print output from VitalSource" width="679" title="Sample print output from VitalSource"></a></p>
<p>That is a sample of the output generated by the interface’s Print
function: an utterly useless, inferior copy of the book that has giant
watermarks on <em>every single page</em>, with the only selectable text in
the whole book being the repugnant threat at the top of each page —
the actual body text of the book is converted to low-resolution,
blurry images, and is therefore neither selectable nor searchable.</p>
<p>Going forward, I will <strong>NEVER</strong> “purchase” anything from Oxford
University Press (and most definitely not from VitalSource), so long
as they have no problem “selling” [access to] DRM-infested copies of
books with no way to download a usable copy of what I paid for.</p>
<p>The key takeaway for me from this whole experience is that due to the
sad and sorry status quo of our current times, this kind of insulting
(mal)treatment of users is all but common, and really can happen to
any one of us. Therefore it is all the more important for us to band
together in protest of this, rather than dividing and isolating
ourselves through misguided better-than-thou sentiments toward
each other.</p>
<p>For Music Copyright, Creativity, and Culture, I ordered and a few days
later received a paper copy from the local bookstore. It’s a copy
I truly own, and can read whenever, wherever, and however I please.</p>
<p>Take care, and so long for now.</p>
<p>References and related links:</p>
<ul>
<li><a href="
https://global.oup.com/academic/help/personal-subscriptions/terms?cc=ca&lang=en&">Terms and Conditions - Oxford University Press</a>
(<a href="
https://kelar.org/~bandali/2025/05/20/oup-terms-and-conditions-2025-05-18.pdf">saved PDF copy as of 2025-08-18</a>)</li>
<li><a href="
https://web.archive.org/web/20250114195332/https://support.vitalsource.com/hc/en-us/articles/28275378380951-Download-PDF-Copy">How do I download or print a PDF copy of my book? - VitalSource</a>
(spoiler: you can’t)</li>
<li><a href="
https://wiki.rossmanngroup.com/VitalSource_%22Lifetime%22_false_advertising">VitalSource “Lifetime” false advertising - Consumer Rights Wiki</a></li>
<li><a href="
https://inv.nadeko.net/watch?v=rk3snANxYMY">The decline of ownership - Louis Rossmann</a></li>
<li><a href="
https://inv.nadeko.net/watch?v=fUwuRtkn2Hk">Does California enforce its laws? HELP ME FIND OUT! - Louis
Rossmann</a></li>
</ul>
]]></content:encoded></item>
</channel></rss>