Monthly Shaarli

All links of one month in a single page.

July, 2025

List repos by number of commits

Number of commits in a git repo can be used as a quick-and-dirty estimation of amount of development time spent in a repo. For variations on this theme, see my previous linkpost.

Here's the bash one-liner I wrote and a few lines of its output:

taha@luxor:~
$ THISPATH="/media/bay/taha/projects/ansible/pub/roles"; find "$THISPATH" -maxdepth 2 -iname ".git" -type d -exec bash -c \
"git -C {} rev-list --count --all | tr '\n' '\t'; echo -e ' ${BGreen}${On_Black}{}${Color_Off}' | \
sed 's+/.git++' | sed 's+$THISPATH/++'" \; | sort -n --reverse -
91   dotfiles
42   R
39   lxd-server
36   python3
36   i3wm
Explainer
  • We will look for git repos inside the /media/bay/taha/projects/ansible/pub/roles directory, and since this path needs to be referenced twice more in the command we can DRY by defining a local var $THISPATH.
  • some roles may contain git submodules, so to avoid including them here we limit depth to only include the top-level .git directory (which is 2 levels down from the search path).
  • get the number of commits (across all branches and authors) for each repo.
  • tr replaces the trailing newline (introduced by output from git -C ...) with a tab so that number and repo name (which we print next) show on the same line.
  • echo -e ' {}' the name of the current repo. I added some colouring for flourish.
  • to save on repitition in the output replace full path returned by find by stripping the trailing .git part as well as the dirname part. Note that this is just my cosmetic preference.
  • sort by numeric value -n and list in --reverse order. Note the trailing dash which references the output from before the pipe.
Links
Ansible gotchas for the forgetful developer

include_tasks files that in turn contain import_tasks cause cryptic errors

It appears to be good practice to avoid using import_tasks in a file if the file itself was included with include_tasks.

Because if you don't, expect to get cryptic error messages like:

# ERROR! Unexpected Exception, this is probably a bug: expected str, bytes or os.PathLike object, not NoneType
Work-arounds to get podcast RSS feeds from those awful closed platforms

Soundcloud

Is the podcast you want to listen to hosted on Soundcloud? First of all, double-check that the podcast is not also hosted somewhere else (more often than not that is the case, and then you can simply avoid Soundcloud).
Soundcloud makes it really hard to discover the podcast's RSS feed. It is not shown anywhere on the page, nor in the HTML source.
Based on a feed URL we already possess and that channel's Soundcloud landing page, we can manually construct the hidden RSS feed endpoint for any Soundcloud "podcast":

  1. Open the HTML source of the Soundcloud "podcast", for example https://soundcloud.com/user-268302561.
  2. In the HTML source, find the user ID property, which looks like soundcloud://users:819898639 (I suggest grep for soundcloud://users).
  3. Copy the numeric part, and construct a URL like this: https://feeds.soundcloud.com/users/soundcloud:users:819898639/sounds.rss.
  4. Take a moment to reflect on the awfulness of siloed web services and do your best to avoid encouraging them in future.
Audiobookshelf - first impressions

I got an instance up and running (obligatory Ansible role https://codeberg.org/ansible/audiobookshelf) and added my audiobooks library to it. Looks very nice :-)

My initial impression is that the audiobooks UX is much better than that of Jellyfin. I will definitely be moving that library to Audiobookshelf.

Podcasts can only be added and episodes downloaded for users with admin privileges, which is a known short-coming with several open issues:

But the UX in the web client is straight-forward as soon as you figure out how to switch between your "libraries" (most commonly "podcasts" and "audiobooks") using the not-so-prominent button just left of the search bar.

Audiobookshelf supports OPML import, and handled my OPML file with almost 150 feeds without choking.

In summary, I am happy to have it up and running and expect it to be my primary venue for audiobook and podcast listening.

beaconDB public domain wireless geolocation database

But I don't understand how to replace Mozilla Locations Services in MicroG with this. I suppose the microg project needs to make that decision, or perhaps I should update microg on the phone (not really possible without re-flashing the whole thing, I assume).