fifteen eleven ninety

tvheadend, fzf and mpv

I wanted to have an easy way to fuzzy find the channel I’d like to watch from my tvheadend’s playlist. After some chit chat with Claude AI I got exactly what I wanted. tvheadend + fzf + mpv = ❤️

import sys
import subprocess
import re
from pathlib import Path

def parse_m3u(content):
	channels = []
	current_name = None

	for line in content.split('\n'):
		if line.startswith('#EXTINF:'):
			match = re.search(r',[^,]*$', line)
			if match:
				current_name = match.group()[1:]
		elif line.startswith('http'):
			if current_name:
				channels.append((current_name, line.strip()))
				current_name = None

	return channels

def main():
	playlist_path = str(Path.home() / "docs" / "playlist")

	# Read and parse the M3U content
	content = open(playlist_path).read()
	channels = parse_m3u(content)

	# Prepare channel names for fzf
	channel_names = '\n'.join(name for name, _ in channels)

	try:
		# Run fzf with --reverse option
		fzf = subprocess.Popen(['fzf', '--reverse'], 
							 stdin=subprocess.PIPE, 
							 stdout=subprocess.PIPE,
							 text=True)
		selected, _ = fzf.communicate(channel_names)

		if fzf.returncode == 0:
			# Find the index of the selected channel
			selected = selected.strip()
			for index, (name, _) in enumerate(channels):
				if name == selected:
					# Launch mpv with the original playlist file
					subprocess.run([
						'mpv',
						f'--playlist-start={index}',
						f'--playlist={playlist_path}'
					])
					break

	except KeyboardInterrupt:
		sys.exit(0)

if __name__ == "__main__":
	main()

Dual boot from Arch into Windows 11

I like to dual boot whenever I want to play some games. This way, I don’t need to install all the proprietary crap on Arch and it feels less of a pain to do so. To make it even easier, I like to use a simple bash alias, which boots into Windows next once I restart my computer.

alias win='sudo efibootmgr --bootnext 0009; reboot'

Tvheadend needs some load

After I’ve moved my tiny homelab server from my desk closer to my living room (who wants to run a cable through his house?), I haven’t been able to establish a stable connection anymore. I’ve got many artifacts and delayed audio all the time. It looks like tvheadend needs some cpu load to prevent continuity counter errors. Other than that, some user on the tvheadend forum found that the issue was far less if USB3 is disabled in bios to avoid using the xhci driver.

I haven’t had this problem when I was using it as a desktop. As of now I’m just running stress-ng --cpu 1 --cpu-load 100. But I’m not that happy about as temperatures and power consumption increase.

AX210

ax210.jpg I just replaced the Intel 8265 AC with an AX210 wifi card in my Thinkpad X280. It was such a nightmare to attach those cables! But it seems to work for now. It is not that I really have a need for all the speed. Maybe it will fix the issues I’ve with eduroam and the connection becomes more stable.

Emacs, eglot and Java

A few days ago, I’ve tried to setup an Emacs environment for Java. I’ve got it working with eglot, the builtin LSP client and jdtls, the only proper language server there is for Java. While it works out of the box, there are a few issues:

  • It looks like jdtls needs some special treatments as it comes with its own features and capabilities. For this reason, someone came up with eglot-java, a java extension for the eglot lsp client. It comes with a few utilities to create and run projects and tests but also the most important one for me: go-to-definition for builtin libraries and 3rd party packages.
  • The connection to the language server isn’t stable at all and interrupts again and again. I tried to run eglot-reconnect without success. In this case, I always had to delete the cache in my emacs user directory. A very slow and painful experience. It looks like other people on the offical #emacs IRC channel have observed something similar so I’m not the only one. This has most probably to do with the quirks jdtls comes with and isn’t emacs fault.

Orgmode site config

I’ve been using hugo before to run this site. While it is super fast, I haven’t been that happy about it. I wanted to create my own theme, but the template lookup order felt like a mess to me. So I just decided to build a simple site with Emacs and use org-mode to publish some html. It is super easy and requires a single variable to setup. I also disabled the builtin styles and scripts and started to use cssbed instead, which is a collection of classless themes.

(setq org-publish-project-alist
	  '(("blog"
		 :base-directory "~/blog"
		 :publishing-function org-html-publish-to-html
		 :publishing-directory "~/blog"
		 :section-numbers nil
		 :with-toc nil
		 :with-date nil
		 :with-author nil
		 :with-creator t
		 :time-stamp-file nil
		 :html-self-link-headlines t
		 :html-head "<link rel=\"stylesheet\" href=\"style.css\">"
		 :html-head-include-scripts nil
		 :html-head-include-default-style nil)))

Adding a grid to my math lecture files

grid.png

I really enjoy using xournal++ for my math course. It allows me to take handwritten notes and annotate my lecture files. While our teacher does a really good job at properly formatting those documents with LaTeX, it always has been hard for me to maintain a straight line on a plain sheet of paper. Unfortunately there is no feature of xournalpp I know of, which would allow me to overlay a grid on top of a pdf file. So I had to come up with something on my own:

grid=$(cat $HOME/docs/grid.svg)

rm -rf /tmp/pdfgrid
mkdir -p $_
mv "$1" $_
cd $_

pdf2svg "$1" %02d.svg all

for page in *.svg; do
	sed -i -e '/<\/svg>/d' $page
	echo "$grid" >> $page
	echo "</svg>" >> $page
done

rsvg-convert -f pdf -o out.pdf *.svg

cd -
mv /tmp/pdfgrid/out.pdf "$1"

I use pdf2svg to slice an entire pdf into an svg file per page. For every page, I append a grid which is just a path with strokes and an opacity. At the end, I use rsvg-convert to assemble the pdf from the svg files again and voilà, all the pages have a grid now!

Detox filenames

So I’ve this weird issue with my tvheadend setup when recording something. I usually want filenames to contain all the meta data, which is useful to me, such as the name of the movie/show or the episode name. Now with over-the-air EPG data, generally speaking, things are not as easy as they should be. It totally depends on the TV channel. Some of them provide no info at all while others provide too much data in a format that contains all kind of special characters. Sanitizing filenames could definitely be improved.

M720q: /pvr l                                                                                                                                      
total 3.8G                                                                                                                                         
drwxrwxrwx 1 root root 8.0K Sep  2 02:01  movies                                                                                                   
drwxrwxrwx 1 root root 4.0K Aug 31 13:09  shows                                                                                                    
-rwxrwxrwx 1 root root 2.0G Sep 10 02:25 'John-Wick-Kabel-Eins.John-Wick'$'\n''Action,-USA-2014'$'\n''Altersfreigabe_-ab-16'$'\n''(WH-vom-Mittwoch,
-04.09.2024,-23_30-Uhr).mkv'                                                                                                                       
-rwxrwxrwx 1 root root 931M Sep 10 12:57  Knight-Rider-Nitro.Das-zweite-Gesicht.mkv                                                                
-rwxrwxrwx 1 root root 933M Sep 10 13:52  Knight-Rider-Nitro.Fahrerflucht.mkv

My go-to solution so far has been to open pcmanfm in that folder, right click the filename and rename it to something more simple. The other day I got to know a better tool for the job. The detox command has been around for a few decades now. I simply run it in the current folder with detox . and I get a filename that I’m able to tab complete again.

M720q: /pvr l
total 3.8G
drwxrwxrwx 1 root root 8.0K Sep  2 02:01 movies
drwxrwxrwx 1 root root 4.0K Aug 31 13:09 shows
-rwxrwxrwx 1 root root 2.0G Sep 10 02:25 John-Wick-Kabel-Eins.John-Wick_Action,-USA-2014_Altersfreigabe-ab-16-WH-vom-Mittwoch,-04.09.2024,-23_30-Uhr.mkv
-rwxrwxrwx 1 root root 931M Sep 10 12:57 Knight-Rider-Nitro.Das-zweite-Gesicht.mkv
-rwxrwxrwx 1 root root 933M Sep 10 13:52 Knight-Rider-Nitro.Fahrerflucht.mkv

The €5 Xbox Digital TV tuner

xbox.jpg

I’ve got a new toy! It is called the Xbox Digital TV Tuner, an official addon from Microsoft for the Xbox One, released more than a decade ago. It is nothing more than a USB cable with a tuner attached to. I’ve got it for cheap from the german kleinaneigen. As someone who lives close to the border, it is usually cheaper to buy stuff from there. I haven’t spent more than 5 bucks on it. And because it’s so cheap, I’ve decided to get 2 more of them! After I’ve tinkered for a while with a DIY barebones solution, I ended up with tvheadend as the streaming server and PVR of my choice. It allows me to watch TV and record the movies and shows I’m interested in. All of that in a totally legal way. Awesome!

tvheadend.jpg

With the triple tv tuner setup I’m able to watch TV while recording two other channels at the same time. While I barely watch live TV anymore these days, with the built in PVR it feels more like a video-on-demand solution such as Netflix or Prime. Macgyver, the A-Team, Knight Rider, Deadliest Catch, Bear Grylls, Reno 911. I’m currently recording a bunch of shows and whatever movie that sounds interesting to me. None of it requires me to spend a single penny.

Selfhosted caddy on a netcup VPS

netcup.png

This blog is self-hosted on netcup’s piko VPS G11s. The cheapest VPS host I could found and for the price it really is a steal! Just EUR 1 a month gets you a virtual private server with:

  • 1 CPU
  • 1 GB RAM
  • 30 GB SSD

The best thing yet to come, custom images to install, including my lovely Arch Linux. Together with a 1.111B Class xyz domain this is a pretty cheap combo! What’s more, it is easier than I thought to get up and running an installation of Contao with the help of Caddy, the ultimate server. All I had to do, was installing caddy from the repositories along with mariadb and php-fpm. The configuration for the server itself couldn’t be any easier:

151190.xyz {
	root * /srv/http/public/
	php_fastcgi unix//run/php-fpm/php-fpm.sock
	encode zstd gzip
	file_server
}

Just to be safe, I set the memory_limit to 512M and call it a day. Who says 13 bucks can’t get you anywhere?

How to setup a local development environment for Contao on Arch Linux

contao.png

I started to use Contao again. After a five year hiatus I can clearly say, it is my favorite CMS nowadays. It still looks and feels the same after all those years, I really appreciate using it. Pages, articles, modules, content elements. Once you got to know about them you don’t want to miss them anymore. The backend is probably the best part about it. The only thing I need is an environment to develop sites locally.

Packages to install:

sudo pacman -S php php-gd php-imagick php-sodium php-fpm composer

Edit the file /etc/php/php-fpm.d/www.conf:

user = manu
group = manu
listen.owner = manu
listen.group = manu

Next, we have to download the Symfony CLI. I just downloaded one of the binaries with wget, extracted the archive and moved it to a location which is in my $PATH. Following this guide, I enabled TLS and started the proxy with symfony server:ca:install and symfony proxy:start. For every project’s root, I attached a domain first once with symfony proxy:domain:attach foo and as soon as I want to start working on the project, I start the server with symfony server:start. After installing Contao, make sure to set the entry point to use the https protocol. To get a list of projects and attached domain names, I usually run symfony proxy:status.

Now the only thing left to do is to tell our web browser about the proxy. Depending on your desktop environment, one can open those settings from the browser, but as I’m using none of the popular ones such as GNOME or KDE, my only choice left is to set an environment variable, which Google Chrome will pick up then. In my ~/.profile file I added:

export auto_proxy="http://M720q:7080/proxy.pac"

This will tell the browser to proxy requests through symfony first. Instead of just using localhost or 127.0.0.1 I decided to use my host name, which allows me to access my sites from any other device in my network (thanks to Tailscale, this even works when I’m not at home). And that’s about it! After a reboot you should now be able to develop your sites locally with Contao.

Extract cookies from $BROWSER

I’ve found this convenient function, which is part of yt-dlp the other day. It allows one to extract cookies from a browser such as Google Chrome, Mozilla Firefox or Microsoft Edge. It could be quite useful if I ever have to scrape something that requires me to login first.

from yt_dlp import cookies

cookies = cookies.extract_cookies_from_browser('edge')
cookies.save('cookies.txt')

Cmus works better with ALSA

It looks like the freezes are gone after switching to alsa as output. I had lots of freezes recently and it was really annoying to listen to my fav’ music. So much that I even tried to come up with alternatives such as mpd, emms and the like. I’m glad those freezes are a problem of the past now. I’ve been using cmus for more than a decade now and I can’t imagine any better way of listening to music without any distractions.

set output_plugin=alsa
set dsp.alsa.device=default
set mixer.alsa.device=default
set mixer.alsa.channel=Master

Der innere Schweinehund

Er ist da, wenn ich ihn gerade nicht brauche. Morgens schon, in aller Früh’. Ein Grunzen, ein Bellen. „Nur noch 5 Minuten länger!“ Er will nicht, noch nicht. Er, der mich immer wieder um den kleinen Finger wickelt. Will er heute wieder mit mir „Gassi gehen“?

Ein Blick auf die Uhr — halbwach und doch verschlafen. Spät, aber nicht zu spät. „Schwein gehabt“, denk ich mir. Die faule Sau, der feige Hund? Nicht mehr hier.

The squirrel from my childhood

What I use

  • Arch Linux as my OS on all my machines
  • Thinkcentre M720t as my main rig with an Intel Core i5 8400, 32 gigs of memory and a GTX 1650 to occasionally play some games
  • Thinkcentre M720q tiny as my server with an Intel Core i5 8400T, 16 gigs of memory and tons of storage, running 24/7 with less than 10W power consumption
  • Thinkpad X280 for everything on the go, 8th gen Intel is still the best bang for the buck and it is even more lightweight than an M1 Macbook Air
  • syncthing to continuously synchronize files between all my machines
  • some random Motorola phone with a recent version of an almost vanilla Android
  • dwm as my tiling window manager of choice
  • GNU/Emacs with Dired and Org mode to organize my life in plain text
  • rsync and rsnapshot for backups, nothing fancy but it does the job
  • pass with passmenu, the standard unix password manager

About

Emacs 29.4 (Org mode 9.4.6)