Skip to main content

Mike Kreuzer

A Ruby interface for the Mastodon API

February 17, 2023

Ruby's library for dealing with Mastodon's API's been left languishing for years. The last release was in January 2019. There are plenty of libraries for dealing with the API written in other languages, complete with web pages & example code. But the language Mastodon's written in? Not so much.

What's especially annoying about this is people have submitted code, but it's been left to sit there, unreviewed. We can still benefit from those other people's hard work though.

I forked one of the forks & merged another fork's code into it to get the two missing features I especially needed, namely the ability to run on a version of Ruby newer than 2.6, and the ability to deal with paginated results.

You can require that version:

gemfile do
  source ''
  gem 'http', '~> 4.0'
  gem 'mastodon-api', git: '', branch: 'merged-forks'
require 'mastodon'

Then after setting up a client in the way suggested in the original README, get paginated results by looping over the API's responses, something like for example:

next_max = nil
results = []
loop do
  data = client.followers(ID, { limit: 80, max_id: next_max })
  next_max = data.next_max_id
  results += data.to_a

  break if next_max.nil?

That code could be abstracted out into a method where you only had to request a number of replies or even no particular number expecting to get all of them, and if there was paging to be done it'd happen under the hood. Pretty easily too.

But that's left as an exercise for the reader, for the same reason I haven't merged the feature branch into main on that forked repo, or renamed the gem & pushed it to RubyGems as a standalone thing. That way lies madness. Or at least open source obligations I'd also be glacially slow to meet.


Blogging, a life in the cheap seats

February 14, 2023

Two things happened in the last few weeks that set me to thinking. One was an article about podcasting, the other was cleaning out my blog feed yesterday. I was moving blogs that hadn't been active in over a year into a folder I (hopefully I thought) called "quiet", & one of them had a link to "an archive of old blog posts from back when blogging was a thing." Ow. Seriously. That hurt.

The article about podcasting said there were 80% fewer new podcasts year on year now, and 13% fewer new episodes from existing podcasts. My own anecdotal experience backs that up, for a while there everybody seemed to be setting up a new podcast, now it seems to only be radio stations and people who are already famous in some way. Which is a shame.

A shame because the people born as they would see it to a certain station in life, are in their own eyes at least the ones who should be the players in life's little theatre; free to do & to say as they please, with the expectation of receiving honours & applause for their exertions.

The rest of us, we're meant to be their audience. We're expected to pay, and to clap appreciatively, & that's it. If we should ever have the temerity to do or to say anything else much we're promptly shushed, usually by the other poor schlubs sitting in the cheap seats right next to us. If we persist in disturbing the peace the ushers in police uniform will surely come to enforce it.

The web, all of it, the great messy glory of it, is an opportunity. An opportunity perhaps to burn the theatre down, & to do something better.

For a while there blogging & podcasting were a big part of that. I think podcasting's going to remain relevant to people, it'll just be different people making the podcasts, people who often already had a platform, but blogging… In November this blog will be ten years old. I'd like to still think blogging was a thing. I read blogs most days, and write here when I can, but it seems there might not be that many of us left dear reader.


Opinionated adventures in remote scripting

February 14, 2023

I've never been especially happy with any of the combinations I've used to script remote machine updates, & now that for the moment I work for myself I've had the luxury of trying to find a better way. Maybe I have. So herewith a few notes on my opinionated adventures in remote scripting.

I started out using Rake, which is what I'd been using to automate local tasks, adding Net::SSH for network connections. That was OK but the network code was clumsy, the opposite of Ruby's usual problem of too much magic, it was completely not magical in any way. It worked, but it was a pain to write, & worse to read.

So for a while there I wrote my own JavaScript task system & added fetch and… yeah, that was worse. Now I'm older & somewhat wiser I tend to think new JavaScript frameworks should be tolerated rather than encouraged. Not because JavaScript's bad in itself, it's not, I've always liked it as a language & have used it pretty much from the start, but what the world didn't need was yet another JavaScript library, & what I really didn't need was another project to maintain. I was & am trying (hard) to wind that back, not to expand it. JavaScript was promising, the task library I wrote was promising – & boy do the very popular JavaScript alternatives to it suck – but I moved on.

After that I tried & pretty quickly rejected Ansible. With only terse 'done' messages or badly broken formatting on replies from the commands on the remote boxes it was by far the worst of the bunch. That's also true when using Ansible for provisioning. I know it's widely used, it's arguably the standard there, but as the saying goes the two most abundant things in the universe are hydrogen & stupidity. See for example the popular JavaScript task runners. Oh boy.

Sticking with Python for a bit I tried Fabric. It was far better than Ansible, & better than Rake/Net::SSH when considered in isolation, but demonstrably much worse once I had to factor in the added pain of creating a virtual environment to run it in every time, just because Python people can't do versioning. (Python… some great ideas, wrapped up in some really terrible execution. Not a million miles from Swift in that respect, but I digress.)

So, back to Rake, but this time with SSHKit from Capistrano, a combination that hit the sweet spot for me. For example I can have a Rake file that in part reads something like:

# frozen_string_literal: true

require 'sshkit'

SSHKit.config.output_verbosity = :debug

desc 'Update pies'
task :update_pies do
  include SSHKit::DSL

  on ['pi1', 'pi2'], in: :sequence, wait: 5 do |host|
    puts host
    execute :sudo, 'apt-get update'
    execute :sudo, 'apt-get full-upgrade -y'

    execute 'pihole -up' if host == 'pi1'

Which updates two Raspberry Pies including updating Pihole on one of them, all with a simple rake update_pies command, while also giving me all the feedback I'd get if I were to SSH in to the boxes & run those commands directly. That's the point I'd got to with Python's Fabric, but SSHKit has none of the pain of having to run Python. If you're stuck using Python for other things perhaps you may want to consider trying Fabric, but it's not worth converting for if you're not already mired in that ecosystem.

These are legacy Pi boxes too of course, after The Pi people set fire to their reputation & all the goodwill they ever had on Mastodon I'll not be getting any more. They were good, until they weren't, time to move on there.

Also, Happy Valentine's Day…


Earlier posts...