slowpoke well

route 33 to the future

Category: Geekery

Automagic Screenshot Twitter Account

I watch a ton of animu. I also take a lot of screenshots while doing so. Occasionally, I will post some of them – mostly the silly or cute ones – to my Twitter Account, sometimes with a more or less funny comment.

Last night. I had the idea of making a separate account so I could spam screenshots as much as I want without annoying my followers too much. I immediately secured @slowpokeshots, then realized it would be pretty cool if I could automate this. Since I had planned to write something interfacing with the Twitter API for quite a while, I quickly looked for some viable libraries, found this nice python package, and set out to hack something together.

Now, some two hours later, I have a working, if somewhat hackish, script that automagically uploads every screenshot I take in mpv (the player you should seriously be using if you’re on any Linux distro) to the aforementioned Twitter account.

Now, how does this work?

The simplest part is actually interfacing and uploading stuff to Twitter. Basically everything is already taken care of by the aforementioned python library, though I had a little derpage with OAuth in the beginning.

The somewhat harder part was interfacing with mpv, which has no API in the strictest sense. What it does have, however, is the ability to read commands from a named pipe (a FIFO file). I’ve fucked around with this a bit before because it essentially allows you to very simply remote control mpv over SSH – you simply echo stuff like “pause” into the file, MPV(1) has a list of all
commands it accepts (see the “List of Input Commands” section).

This input file must either be passed to mpv with every invocation via –input-file, or configured in ~/.mpv/config. In my case, it’s set to /tmp/mpv.fifo, which is created during X startup.

Now, there are three commands for mpv of interest: screenshot, screenshot_to_file, and run.

The first two are somewhat self-explaining. screenshot takes a shot, named according to whatever is specified in the screenshot-template option. In my case, it will put them into ~/screenshots and name it after the filename of the video plus a four digit incrementing number (again, see MPV(1) for how to configure screenshot-template). This is not super-important to the use case at hand, but I thought I’d mention it.

screenshot_to_file, as the name implies, takes a filename as an argument, where it will save the taken screenshot. Both screenshot and screenshot_to_file take an optional argument (first argument for the former, second for the latter) which decides whether subtitles are included in the screenshot (“subtitles”, the default if nothing is given) or not (“video”). Per default, screenshot subtitles is bound to s in mpv, and screenshot video to S. I use both quite a lot.

run is for running shell commands, nothing much more to explain about it.

Now, what my script does is the following: when called, it will use the aforementioned named pipe to tell mpv to take a screenshot to a specified location with screenshot_to_file, then another regular screenshot (because I want my shots archived), waits for the first shot to appear, and uploads it to Twitter. I’ve bound this script, using the run command, to the keys formerly used for taking screenshots – the whole process is transparent.

I’ve posted the code to a gist because I don’t think I’m gonna change anything about it in the future (and if I do, I can still put it in a repository proper).

It’s public domain. Use it if you like it (you might want to change the API keys and make your own version, though).

Advertisements

Fun with UEFI

As a matter of fact, the title of this post is not meant in a sarcastic fashion. If you’ve come here thinking this is a rant about (U)EFI, I’ve got to disappoint you. :)

Anyways, since my SSD recently died and my backups were, ahem, lackluster, I had to set up my system from scratch. Since I didn’t really like the previous setup (LVM on LUKS) anyways, I figured I might as well try root on ZFS again. And if I’m at it, boot the whole thing with UEFI.

Now, I’ve heard some people curse UEFI like it’s the second coming of Bill Gates, and that it’s a royal pain in the ass to get working, etc. As I’m currently writing this from my shiny, new system booting from UEFI, you might guess that I can’t confirm this notion – though your mileage might vary.

Setup

Let’s get started, by stating the initial goal of the install:

  • a shiny new Gentoo GNU/Linux
  • booting entirely off ZFS
  • from within an encrypted LUKS partition
  • without a bootloader
  • and nothing besides the kernel outside of the crypted partition

For the most part, I’ve followed the UEFI Quick Install Guide and the excellent Gentoo Handbook, with a bit of duck-fu on the side. This worked pretty smoothly, and I had no noteworthy problems with getting the entire thing to work.

Now, the interesting part, and the question that most of you will probably have had while reading the list of goals:

“How in the name of Eris are you supposed to boot an encrypted system running off ZFS without a bootloader or an initram?”

How it works

Enter two (more ore less) little-known Linux kernel configuration options: CONFIG_INITRAMFS_SOURCE and CONFIG_CMDLINE. What do they do? Let’s start with the latter: CONFIG_CMDLINE specifies a built-in kernel command line for Linux. Normally, you’d pass options to the kernel from the bootloader, but you can also compile a fixed default one into the kernel. Here is mine (stripped of a few uninteresting things):

CONFIG_CMDLINE="crypt_root=UUID=blahblah real_root=ZFS=KOS-MOS/ROOT/gentoo dozfs=force ro"

The options you see here are used by an initram generated with Gentoo’s genkernel utility, which brings us directly to the other option, CONFIG_INITRAMFS_SOURCE. This option takes a path to a cpio-compressed initram, and builds it directly into the kernel – and that is pretty much the entire magic behind this setup.

Implications

This setup has a few cool side effects, but the most important one is that there is only a single attack vector outside of the encrypted partition (well, two if you count the UEFI implementation). I’ve not tried this yet, but it should be possible to sign the kernel and activate Secure Boot, which would enable a completely trusted boot chain. I’m gonna fuck around with kernel signing a bit this week and maybe post a follow-up.

Caveats

I’m not gonna lie, this setup has its downsides, too. First of all, it’s a pain in the ass to have to recompile (parts of) the kernel if you need to change the boot options. The same goes for changing something in the initram (though I only have to do this very rarely). It’s severely inflexible.