<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>hi, it&#39;s mike</title>
    <link>https://mike.puddingtime.org/tags/rss/</link>
    <description>Recent content on hi, it&#39;s mike</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <managingEditor>mike@puddingtime.org (mike)</managingEditor>
    <webMaster>mike@puddingtime.org (mike)</webMaster>
    <copyright>© 2026, mike</copyright>
    <lastBuildDate>Mon, 29 Jan 2024 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://mike.puddingtime.org/tags/rss/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>A Wallabag bookmarking script for Newsboat</title>
      <link>https://mike.puddingtime.org/posts/2024-01-29-a-wallabag-bookmarking-script-for-newsboat/</link>
      <pubDate>Mon, 29 Jan 2024 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2024-01-29-a-wallabag-bookmarking-script-for-newsboat/</guid>
      <description>Ruby and httparty worked where a simple bash script wouldn&amp;rsquo;t. Letting Newsboat have two bookmarking commands.</description>
      <content:encoded><![CDATA[<p>I don&rsquo;t have any idea what was going wrong where, but I found a &ldquo;post to Wallabag&rdquo; (<a href="/posts/2024-01-28-daily-notes/">previously</a>) sh script that worked great from the command line, but wouldn&rsquo;t run within Newsboat. So I took the script apart, converted it to Ruby/httparty, and it runs fine in this form.</p>
<p>Now I have two scripts for bookmarking in Newsboat, but it only has one reserved key for bookmarking a post. It does have macros, though, so you can use one to set the bookmarking command to a given script and bind it to something memorable. My mutt convention is to lead macros with a period, so I kept that here by unbinding Newsboat&rsquo;s default macro prefix (,) and setting &ldquo;.&rdquo;.</p>
<p>So, <kbd>.l</kbd> to save to Linkding, <kbd>.w</kbd> to save to Wallabag:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># macros</span>
</span></span><span class="line"><span class="cl">bind-key . macro-prefix
</span></span><span class="line"><span class="cl">unbind-key ,
</span></span><span class="line"><span class="cl">macro w <span class="nb">set</span> bookmark-cmd <span class="s2">&#34;op run --env-file=\&#34;</span><span class="nv">$HOME</span><span class="s2">/.env\&#34; -- ~/bin/wallabag.rb&#34;</span><span class="p">;</span> bookmark
</span></span><span class="line"><span class="cl">macro l <span class="nb">set</span> bookmark-cmd <span class="s2">&#34;op run --env-file=\&#34;</span><span class="nv">$HOME</span><span class="s2">/.env\&#34; -- ~/bin/linkding.rb&#34;</span><span class="p">;</span> bookmark</span></span></code></pre></div>
<p>And here&rsquo;s the Wallabag bookmarking script:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="ch">#!/usr/bin/env ruby</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">require</span> <span class="s1">&#39;httparty&#39;</span>
</span></span><span class="line"><span class="cl"><span class="nb">require</span> <span class="s1">&#39;json&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">entry_url</span> <span class="o">=</span> <span class="no">ARGV</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">wallabag_url</span><span class="o">=</span><span class="s2">&#34;https://reader.example.net&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">client_id</span> <span class="o">=</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;WALLABAG_CLIENT&#39;</span><span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="n">client_secret</span> <span class="o">=</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;WALLABAG_SECRET&#39;</span><span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="n">username</span> <span class="o">=</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;WALLABAG_USER&#39;</span><span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="n">password</span> <span class="o">=</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;WALLABAG_PASSWORD&#39;</span><span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">token_params</span> <span class="o">=</span> <span class="p">{</span><span class="ss">grant_type</span><span class="p">:</span> <span class="s2">&#34;password&#34;</span><span class="p">,</span> <span class="ss">client_id</span><span class="p">:</span> <span class="n">client_id</span><span class="p">,</span> <span class="ss">client_secret</span><span class="p">:</span> <span class="n">client_secret</span><span class="p">,</span> <span class="ss">username</span><span class="p">:</span> <span class="n">username</span><span class="p">,</span> <span class="ss">password</span><span class="p">:</span> <span class="n">password</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="n">token_req</span> <span class="o">=</span> <span class="no">HTTParty</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="s2">&#34;</span><span class="si">#{</span><span class="n">wallabag_url</span><span class="si">}</span><span class="s2">/oauth/v2/token&#34;</span><span class="p">,</span> <span class="ss">body</span><span class="p">:</span> <span class="n">token_params</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">access_token</span> <span class="o">=</span> <span class="n">token_req</span><span class="o">[</span><span class="s2">&#34;access_token&#34;</span><span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">headers</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;Content-Type&#39;</span> <span class="o">=&gt;</span> <span class="s2">&#34;application/json&#34;</span><span class="p">,</span> <span class="s1">&#39;Authorization&#39;</span> <span class="o">=&gt;</span> <span class="s2">&#34;Bearer </span><span class="si">#{</span><span class="n">access_token</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="n">params</span> <span class="o">=</span> <span class="p">{</span><span class="ss">url</span><span class="p">:</span> <span class="n">entry_url</span><span class="p">,</span> <span class="ss">starred</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="ss">archive</span><span class="p">:</span> <span class="mi">0</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="n">resp</span> <span class="o">=</span> <span class="no">HTTParty</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="s2">&#34;</span><span class="si">#{</span><span class="n">wallabag_url</span><span class="si">}</span><span class="s2">/api/entries.json&#34;</span><span class="p">,</span> <span class="ss">body</span><span class="p">:</span> <span class="n">params</span><span class="o">.</span><span class="n">to_json</span><span class="p">,</span> <span class="ss">headers</span><span class="p">:</span> <span class="n">headers</span><span class="p">)</span></span></span></code></pre></div>
]]></content:encoded>
    </item>
    <item>
      <title>Daily Notes for 2024-01-26</title>
      <link>https://mike.puddingtime.org/posts/2024-01-26-daily-notes/</link>
      <pubDate>Fri, 26 Jan 2024 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2024-01-26-daily-notes/</guid>
      <description>Sorta the mutt of RSS readers. Scripting the Linkding API.</description>
      <content:encoded><![CDATA[<h2 id="sorta-the-mutt-of-rss-readers">Sorta the mutt of RSS readers</h2>
<p><a href="https://newsboat.org/">Newsboat</a> is pretty cool! It&rsquo;s a plaintext RSS reader that has strong affinities for mutt in look and configuration.</p>
<p>Like mutt, it might not crowd out everything else in the toolbox but it can help you burn through the subscription list and triage even if you have more comfortable ways of reading the content you process.</p>
<p>It also has built-in filtering. If you&rsquo;re using an RSS provider that already does that, e.g. FreshRSS or Feedly, that might not be super valuable, but it&rsquo;s easy to make a killfile either way:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">ignore-mode display
</span></span><span class="line"><span class="cl">ignore-article &#34;*&#34; &#34;link =~ \&#34;/ducks/\&#34;&#34;
</span></span><span class="line"><span class="cl">ignore-article &#34;*&#34; &#34;link =~ \&#34;/advice/\&#34;&#34;
</span></span><span class="line"><span class="cl">ignore-article &#34;*&#34; &#34;link =~ \&#34;/nfl/\&#34;&#34;
</span></span><span class="line"><span class="cl">ignore-article &#34;*&#34; &#34;link =~ \&#34;/beavers/\&#34;&#34;
</span></span><span class="line"><span class="cl">ignore-article &#34;*&#34; &#34;link =~ \&#34;/blazers/\&#34;&#34;
</span></span><span class="line"><span class="cl">ignore-article &#34;*&#34; &#34;link =~ \&#34;/highschoolsports/\&#34;&#34;
</span></span><span class="line"><span class="cl">ignore-article &#34;*&#34; &#34;link =~ \&#34;/entertainment/\&#34;&#34;
</span></span><span class="line"><span class="cl">ignore-article &#34;*&#34; &#34;link =~ \&#34;/realestate-news/\&#34;&#34;
</span></span><span class="line"><span class="cl">ignore-article &#34;*&#34; &#34;link =~ \&#34;/food/\&#34;&#34;
</span></span><span class="line"><span class="cl">ignore-article &#34;*&#34; &#34;link =~ \&#34;/hawks/\&#34;&#34;</span></span></code></pre></div>
<h2 id="scripting-the-linkding-api-to-make-a-bookmark-function-for-newsboat">Scripting the Linkding API to make a bookmark function for Newsboat</h2>
<p>If you like reading longform plaintext maybe Newsboat is all you need. I tend to treat RSS as a two-step process: See an interesting thing, send it to some sort of RIL or bookmarking service. Newsboat has a bookmarking function you can customize with your own scripts. It just passes the article URL, title, description, and website description to your script, which has to talk to whatever API. There are a bunch of <a href="https://github.com/newsboat/newsboat/tree/master/contrib">examples in the Newsboat contrib directory</a> for things like Pocket, Pinboard, and Evernote. No Linkding, but <a href="https://github.com/sissbruecker/linkding/blob/master/docs/API.md">the Linkding API</a> is simple enough.</p>
<p>Could be simpler but I bounced off of <kbd>net:http</kbd> in my formative years:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="ch">#!/usr/bin/env ruby</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">require</span> <span class="s1">&#39;httparty&#39;</span>
</span></span><span class="line"><span class="cl"><span class="nb">require</span> <span class="s1">&#39;json&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">linkding_uri</span> <span class="o">=</span> <span class="s2">&#34;https://links.puddingtime.net/api/bookmarks/&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Get your Linkding API key from Settings &gt; Integrations</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">token</span> <span class="o">=</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;LINKDING&#39;</span><span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">link_url</span> <span class="o">=</span> <span class="no">ARGV</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="n">link_title</span> <span class="o">=</span> <span class="no">ARGV</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="n">description</span> <span class="o">=</span> <span class="no">ARGV</span><span class="o">[</span><span class="mi">2</span><span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="n">website_title</span> <span class="o">=</span> <span class="no">ARGV</span><span class="o">[</span><span class="mi">3</span><span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">params</span> <span class="o">=</span> <span class="p">{</span><span class="ss">url</span><span class="p">:</span> <span class="no">URI</span><span class="p">(</span><span class="n">link_url</span><span class="p">),</span> <span class="ss">title</span><span class="p">:</span> <span class="n">link_title</span><span class="p">,</span> <span class="ss">website_title</span><span class="p">:</span> <span class="n">website_title</span><span class="p">,</span> <span class="ss">unread</span><span class="p">:</span> <span class="kp">true</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="n">headers</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;Content-Type&#39;</span> <span class="o">=&gt;</span> <span class="s2">&#34;application/json&#34;</span><span class="p">,</span> <span class="s1">&#39;Authorization&#39;</span> <span class="o">=&gt;</span> <span class="s2">&#34;Token </span><span class="si">#{</span><span class="n">token</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">resp</span> <span class="o">=</span> <span class="no">HTTParty</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">linkding_uri</span><span class="p">,</span> <span class="ss">body</span><span class="p">:</span> <span class="n">params</span><span class="o">.</span><span class="n">to_json</span><span class="p">,</span> <span class="ss">headers</span><span class="p">:</span> <span class="n">headers</span><span class="p">)</span></span></span></code></pre></div>
]]></content:encoded>
    </item>
    <item>
      <title>Full content in the RSS feed (and how to add a second Hugo feed)</title>
      <link>https://mike.puddingtime.org/posts/2023-05-18-full-content-in-the-rss-feed/</link>
      <pubDate>Thu, 18 May 2023 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-05-18-full-content-in-the-rss-feed/</guid>
      <description>There&amp;rsquo;s finally a full-content RSS feed here.</description>
      <content:encoded><![CDATA[<p>It took me a while to figure it out after a failed first attempt, but I finally made a <a href="https://mike.puddingtime.org/index.xml">full-content RSS feed.</a> It&rsquo;s going under the same name as it was before as a partial feed, so it ought to just start providing the full content of posts now.</p>
<p>Previously I was using a modified feed that was meant to work well for social syndication (e.g. cross-posting to Mastodon and Twitter). It included just the post summary plus + tags as a way to aid with discovery (especially in Mastodon). That didn&rsquo;t sit super well with me &ndash; I&rsquo;m a &ldquo;full content&rdquo; kind of person &ndash; but figuring out how to get Hugo to do two feeds took some doing.</p>
<p>While I was in there, I also shortened the length of the feeds to 20 posts. I think there are a few more things to do to make it all work just so, but I&rsquo;m content to just have a full content feed back in place for now.  Also, if you liked the old feed format (I guess some people like summaries and clicking through?) it&rsquo;s still around, but I renamed it to <a href="https://mike.puddingtime.org/social.xml">/social.xml</a>, since its primary purpose is driving an <a href="https://ifttt.com">IFTTT</a> cross-posting recipe.</p>
<h2 id="setting-it-up">Setting it up</h2>
<p>If you&rsquo;re curious about how the two feeds are configured:</p>
<p>First, you need two template files in your site&rsquo;s <code>layouts/_default</code> directory:</p>
<ul>
<li><code>rss.xml</code></li>
<li><code>list.socialrss.xml</code></li>
</ul>
<p>The first one is a <a href="https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates/_default/rss.xml">standard Hugo RSS template</a> with a slight modification to the <code>description</code> property to use the full content of a post vs. the summary.</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">description</span><span class="p">&gt;</span>{{ .Content | html }}<span class="p">&lt;/</span><span class="nt">description</span><span class="p">&gt;</span></span></span></code></pre></div>
<p>The second template uses the post summary, and adds a partial:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">description</span><span class="p">&gt;</span>{{ .Summary | html }} <span class="p">&lt;</span><span class="nt">br</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">   {{ partial &#34;rss_tags.html&#34; . }}
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">description</span><span class="p">&gt;</span></span></span></code></pre></div>
<p>The partial is how I get post tags for use in syndication to the social feed. Mastodon clients tend to auto-link hashtags, and hashtags are key to discovery in Mastodon:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">{{- $tags := .Language.Params.Taxonomies.tag | default &#34;tags&#34; }}
</span></span><span class="line"><span class="cl">{{- range ($.GetTerms $tags) }} #{{ .LinkTitle }}  {{- end }}</span></span></code></pre></div>
<p><code>config.yml</code> looks like this in my setup:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">outputs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">home</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">HTML</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">RSS</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">SocialRSS</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">JSON</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">outputFormats</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">RSS</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">mediatype</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;application/rss+xml&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">baseName</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;index&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">isPlainText</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">notAlternative</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">SocialRSS</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">mediatype</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;application/rss+xml&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">baseName</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;social&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">isPlainText</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">mediaTypes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="s2">&#34;application/rss&#34;</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">suffixes</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;xml&#34;</span><span class="p">]</span></span></span></code></pre></div>
]]></content:encoded>
    </item>
  </channel>
</rss>
