summary refs log tree commit diff
path: root/.config/waybar/modules
diff options
context:
space:
mode:
Diffstat (limited to '.config/waybar/modules')
-rwxr-xr-x.config/waybar/modules/covid.sh85
-rwxr-xr-x.config/waybar/modules/gamma.go78
-rw-r--r--.config/waybar/modules/go.mod5
-rw-r--r--.config/waybar/modules/go.sum4
-rwxr-xr-x.config/waybar/modules/hotspots.sh21
-rwxr-xr-x.config/waybar/modules/mediaplayer.py171
-rw-r--r--.config/waybar/modules/mpris.awk54
-rwxr-xr-x.config/waybar/modules/mpris.sh6
-rwxr-xr-x.config/waybar/modules/timetracked.sh23
-rwxr-xr-x.config/waybar/modules/todo.go229
-rwxr-xr-x.config/waybar/modules/toggl.lua28
-rwxr-xr-x.config/waybar/modules/vpn.sh24
-rwxr-xr-x.config/waybar/modules/weather.sh42
13 files changed, 0 insertions, 770 deletions
diff --git a/.config/waybar/modules/covid.sh b/.config/waybar/modules/covid.sh
deleted file mode 100755
index 46727d7..0000000
--- a/.config/waybar/modules/covid.sh
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/bin/sh
-
-set -e
-[ -n "$DEBUG" ] && {
-	set -x
-	curl_args='-v'
-}
-
-# check requirements
-for tool in awk curl jq flock; do
-	if ! command -v "$tool" >/dev/null; then
-		printf "%s: %s not installed but required\n" "$(basename "$0")" "$tool" >&2
-		exit 1
-	fi
-done
-
-# incidence = (sumCasesLast7Days / EWZ) * 100000
-lat=${HOME_LAT:?}
-lon=${HOME_LON:?}
-# fields='GEN,RS,EWZ,EWZ_BL,BL_ID,cases,cases_per_100k,cases7_per_100k,cases7_bl_per_100k,last_update,BL,IBZ'
-fields='GEN,cases7_bl_per_100k'
-# see https://experience.arcgis.com/experience/478220a4c454480e823b17327b2bf1d4
-uri="https://services7.arcgis.com/mOBPykOjAyBO2ZKk/arcgis/rest/services/RKI_Landkreisdaten/FeatureServer/0/query?where=1%3D1&outFields=${fields}&geometry=${lon}%2C${lat}&geometryType=esriGeometryPoint&inSR=4326&spatialRel=esriSpatialRelWithin&returnGeometry=false&outSR=4326&f=json"
-
-_data=$(curl -sSL -H 'Accept: application/json' ${curl_args} "${uri}" | jq -r '.features[0].attributes')
-if [ "${_data}" = "null" ]; then
-	printf "{}\n"
-	exit 0
-fi
-
-historical_data=${HOME}/covid-history.csv
-loc=$(printf "%s" "${_data}" | jq -r '.GEN')
-last_update=$(printf "%s" "${_data}" | jq -r '.last_update')
-# printf "${_data}" | jq -r '.'
-incidence_f=$(printf "%.1f" "$(printf "%s" "${_data}" | jq -r '.cases7_bl_per_100k')")
-incidence_i=$(printf "%.0f" "${incidence_f}")
-
-# store
-if [ -n "${last_update}" ] && [ -n "${incidence_f}" ]; then
-	tmp_HISTFILE=$(mktemp -u --tmpdir waybar-module-covid.XXXXX)
-	(
-		cat "${historical_data}"
-		ts=$(printf "%s" "${last_update}" | cut -d',' -f1 | tr '.' '-')
-		printf "%s,%s\n" "${ts}" "${incidence_f}"
-	) | uniq | tee "${tmp_HISTFILE}" >/dev/null
-	flock -x "${historical_data}" mv "${tmp_HISTFILE}" "${historical_data}"
-fi
-
-mxy=$(tail -n 7 "${historical_data}" | awk -F',' '{y=y+$2} END{print ((NR*(NR+1))/2)/NR, y/NR}')
-trend=$(awk -F',' --assign="mx=$(printf "%s" "$mxy" | cut -d' ' -f1)" --assign="my=$(printf "%s" "$mxy" | cut -d' ' -f2)" '{up= up+(NR-mx)*($2-my); down= down+(NR-mx)**2} END{if(down==0){print 0}else{print up/down};}' "${historical_data}")
-trend_arrow="󰔴"
-[ "$(printf "%.0f" "${trend}")" -gt 0 ] && trend_arrow="󰔵"
-[ "$(printf "%.0f" "${trend}")" -lt 0 ] && trend_arrow="󰔳"
-
-color='green'
-if [ "${incidence_i}" -eq "0" ]; then
-	color='gray'
-fi
-if [ "${incidence_i}" -gt "1" ]; then
-	color='green'
-fi
-if [ "${incidence_i}" -gt "25" ]; then
-	color='yellow'
-fi
-if [ "${incidence_i}" -gt "35" ]; then
-	color='orange'
-fi
-if [ "${incidence_i}" -gt "50" ]; then
-	color='red'
-fi
-if [ "${incidence_i}" -gt "100" ]; then
-	color='darkred'
-fi
-if [ "${incidence_i}" -gt "250" ]; then
-	color='darkdarkred'
-fi
-
-tooltip="7 Tage Inzidenz für ${loc}
-last update: ${last_update}
-
-history (${trend_arrow}):
-$(awk -F, '{print $1 " " $2}' "${historical_data}" | tail -n10 | tac)"
-
-jq -nr \
-	"{ text: \"${trend_arrow}${incidence_f}\", percentage: \"${incidence_i}\", class: \"${color}\", alt: \"${color}\", tooltip: \"${tooltip}\" } | @text"
diff --git a/.config/waybar/modules/gamma.go b/.config/waybar/modules/gamma.go
deleted file mode 100755
index 9813cc8..0000000
--- a/.config/waybar/modules/gamma.go
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/usr/bin/env yaegi
-
-package main
-
-import (
-	"encoding/json"
-	"log"
-	"os"
-	"os/exec"
-	"os/signal"
-	"runtime"
-	"strings"
-	. "syscall"
-)
-
-func main() {
-	runtime.GOMAXPROCS(1)
-
-	var (
-		update = make(chan os.Signal, 1)
-		cancel = make(chan os.Signal, 1)
-	)
-	signal.Notify(update, SIGUSR1, SIGUSR2, SIGHUP)
-	signal.Notify(cancel, SIGTERM, SIGINT)
-
-	// could use golang.org/x/sys/unix.Prctl here
-	// but I want to avoid the dependency
-	if _, _, e := Syscall6(uintptr(SYS_PRCTL),
-		uintptr(PR_SET_PDEATHSIG),
-		uintptr(SIGTERM),
-		0, 0, 0, 0); e != 0 {
-		log.Fatalf("error: %v", e)
-	}
-
-	lookup()
-	for {
-		select {
-		case sig := <-update:
-			switch sig {
-			case SIGUSR1:
-				printJson("day")
-				// TODO(robert): toggle wlsunset off?
-			case SIGUSR2:
-				printJson("night")
-				// TODO(robert): toggle wlsunset on?
-			case SIGHUP:
-				lookup()
-			}
-		case <-cancel:
-			log.Printf("%v exiting\n", os.Args[0])
-			os.Exit(0)
-		}
-	}
-}
-
-func printJson(phase string) {
-	_ = json.NewEncoder(os.Stdout).Encode(map[string]interface{}{
-		"class":   phase,
-		"alt":     phase,
-		"tooltip": "gamma: " + phase,
-		"text":    phase,
-	})
-}
-
-func lookup() {
-	cmdEnv, ok := os.LookupEnv("GAMMA_COMMAND")
-	if !ok {
-		printJson("unknown")
-		return
-	}
-	b, err := exec.Command("bash", "-c", cmdEnv).Output()
-	if err != nil {
-		log.Fatalf("error: %v", err)
-		return
-	}
-	phase := strings.TrimSpace(string(b))
-	printJson(phase)
-}
diff --git a/.config/waybar/modules/go.mod b/.config/waybar/modules/go.mod
deleted file mode 100644
index fdeae95..0000000
--- a/.config/waybar/modules/go.mod
+++ /dev/null
@@ -1,5 +0,0 @@
-module git.sr.ht/~robertgzr/dotfiles/.config/waybar/modules
-
-go 1.15
-
-require github.com/fsnotify/fsnotify v1.4.9 // indirect
diff --git a/.config/waybar/modules/go.sum b/.config/waybar/modules/go.sum
deleted file mode 100644
index b12c1ed..0000000
--- a/.config/waybar/modules/go.sum
+++ /dev/null
@@ -1,4 +0,0 @@
-github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
-github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
-golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9 h1:L2auWcuQIvxz9xSEqzESnV/QN/gNRXNApHi3fYwl2w0=
-golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
diff --git a/.config/waybar/modules/hotspots.sh b/.config/waybar/modules/hotspots.sh
deleted file mode 100755
index fe2ff65..0000000
--- a/.config/waybar/modules/hotspots.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash
-set -e
-
-case "$1" in
-click)
-	uri=$(hspl -u)
-	xdg-open "http://$uri"
-	;;
-*)
-	output=$(hspl || echo "none")
-	if [ "$output" != "none" ]; then
-		jq -nc \
-			--arg text "󱛄 $(head -n1 <<<"$output")" \
-			--arg tooltip "$(tail -n+2 <<<"$output")" \
-			--arg class "$(if [ "$(hspl -d)" -lt 100 ]; then echo "soon"; else echo ""; fi)" \
-			'{text:$text,tooltip:$tooltip,class:$class}'
-	else
-		jq -nc '{}'
-	fi
-	;;
-esac
diff --git a/.config/waybar/modules/mediaplayer.py b/.config/waybar/modules/mediaplayer.py
deleted file mode 100755
index 8082825..0000000
--- a/.config/waybar/modules/mediaplayer.py
+++ /dev/null
@@ -1,171 +0,0 @@
-#!/usr/bin/env python3
-
-import argparse
-import json
-import logging
-import signal
-import sys
-from datetime import timedelta
-from math import floor
-import prctl
-
-# yapf: disable
-import gi
-gi.require_version('Playerctl', '2.0')
-from gi.repository import GLib, Playerctl
-# yapf: enable
-
-logger = logging.getLogger(__name__)
-loop = GLib.MainLoop()
-
-def write_output(text, player):
-    logger.info('Writing output')
-
-    output = {
-        'text': text,
-        'class': player.props.player_name,
-        'alt': player.props.player_name
-    }
-    sys.stdout.write(json.dumps(output) + '\n')
-    sys.stdout.flush()
-
-
-def on_play(player, status, manager):
-    logger.info('Received new playback status')
-    on_metadata(player, player.props.metadata, manager)
-
-
-def on_metadata(player, metadata, manager):
-    logger.info('Received new metadata')
-    track_info = ''
-
-    if player.props.player_name == 'spotify' and \
-            'mpris:trackid' in metadata.keys() and \
-            ':ad:' in player.props.metadata['mpris:trackid']:
-        track_info = 'AD PLAYING'
-
-    if player.get_title() and player.get_title() != '':
-        track_info = f"{player.get_title()}"
-    if player.get_artist() and player.get_artist() != '':
-        track_info = f"{player.get_artist()} - {track_info}"
-
-    if 'mpris:length' in player.props.metadata.keys():
-        dur_td = timedelta(microseconds=player.props.metadata['mpris:length'])
-        dur_h, remainder = divmod(dur_td.total_seconds(), 3600)
-        dur_m, dur_s = divmod(remainder, 60)
-        dur = f"{floor(dur_m)}:{floor(dur_s):02}"
-        if dur_h > 0:
-            dur = f"{floor(dur_h)}:{dur}"
-        track_info = '{} ({})'.format(track_info, str(dur))
-
-    if player.props.status == 'Paused' and track_info:
-        track_info = '<i>'+track_info+'</i>'
-
-    if player.props.status == 'Stopped':
-        return
-
-    if track_info == '':
-        logger.warning('TrackInfo was empty after parsing')
-        return
-
-    write_output(track_info, player)
-
-
-def on_player_appeared(manager, player, selected_player=None, ignored_players=None):
-    if player is not None \
-            and (selected_player is None or player.name == selected_player) \
-            and not (player.name in ignored_players):
-        init_player(manager, player)
-    else:
-        logger.debug(
-            "New player appeared, but it's not the selected player, skipping")
-
-
-def on_player_vanished(manager, player):
-    logger.info('Player has vanished')
-    sys.stdout.write('\n')
-    sys.stdout.flush()
-
-
-def init_player(manager, name):
-    logger.debug('Initialize player: {player}'.format(player=name.name))
-    player = Playerctl.Player.new_from_name(name)
-    player.connect('playback-status', on_play, manager)
-    player.connect('metadata', on_metadata, manager)
-    manager.manage_player(player)
-    on_metadata(player, player.props.metadata, manager)
-
-
-def signal_handler(sig, frame):
-    logger.warning('Received signal to stop, exiting')
-    sys.stdout.write('\n')
-    sys.stdout.flush()
-    loop.quit()
-    sys.exit(0)
-
-
-def parse_arguments():
-    parser = argparse.ArgumentParser()
-
-    # Increase verbosity with every occurance of -v
-    parser.add_argument('-v', '--verbose', action='count', default=0)
-
-    # Define for which player we're listening
-    parser.add_argument('--player',
-                        help='player to listen for')
-
-    # Define which players to ignore entirely
-    parser.add_argument('-I', '--ignore',
-                        action='append',
-                        help='players to ignore')
-
-    return parser.parse_args()
-
-
-def main():
-    arguments = parse_arguments()
-
-    # Initialize logging
-    logging.basicConfig(stream=sys.stderr,
-                        level=logging.DEBUG,
-                        format='%(name)s %(levelname)s %(message)s')
-
-    # Logging is set by default to WARN and higher.
-    # With every occurrence of -v it's lowered by one
-    logger.setLevel(max((3 - arguments.verbose) * 10, 0))
-
-    # Log the sent command line arguments
-    logger.debug('Arguments received {}'.format(vars(arguments)))
-
-    manager = Playerctl.PlayerManager()
-    manager.connect('name-appeared',
-                    lambda *args: on_player_appeared(*args, arguments.player, arguments.ignore))
-    manager.connect('player-vanished', on_player_vanished)
-
-    # set the process up to die when the parent exits
-    prctl.set_pdeathsig(signal.SIGTERM)
-
-    signal.signal(signal.SIGINT, signal_handler)
-    signal.signal(signal.SIGTERM, signal_handler)
-    signal.signal(signal.SIGHUP, signal_handler)
-
-    for player in manager.props.player_names:
-        if arguments.player is not None and arguments.player != player.name:
-            logger.debug(
-                '{player} is not the filtered player, skipping it'.format(
-                    player=player.name))
-            continue
-
-        if arguments.ignore is not None and player.name in arguments.ignore:
-            logger.debug(
-                '{player} is ignored, skipping it'.format(
-                    player=player.name))
-            continue
-
-        init_player(manager, player)
-
-    loop.run()
-
-
-if __name__ == '__main__':
-    main()
diff --git a/.config/waybar/modules/mpris.awk b/.config/waybar/modules/mpris.awk
deleted file mode 100644
index 194aa73..0000000
--- a/.config/waybar/modules/mpris.awk
+++ /dev/null
@@ -1,54 +0,0 @@
-{
-  gsub(/"/,"")
-  gsub(/'/,"\047")
-  # print "DEBUG: " $0
-
-  artist=$1
-  album=$2
-  title=$3
-  position=$4
-  player=$5
-  status=$6
-}
-
-($0 == "") || (status ~ /stopped/) {
-  system("jq -Mnc {}")
-  next
-}
-
-(status ~ /playing/) {
-  icon="󰲸"
-}
-(status ~ /paused/) {
-  icon="󰏤"
-}
-(artist != "") && (album != "") {
-  text=sprintf("%s - %s - %s (%s)", artist, album, title, position)
-  tooltip=sprintf("%s\nby %s\nfrom %s\n(%s)", title, artist, album, player)
-}
-(artist == "") {
-  text=sprintf("%s - %s (%s)", album, title, position)
-  tooltip=sprintf("%s\nfrom %s\n(%s)", title, album, player)
-}
-(album == "") {
-  text=sprintf("%s - %s (%s)", artist, title, position)
-  tooltip=sprintf("%s\nby %s\n(%s)", title, artist, player)
-}
-(artist == "") && (album == "") {
-  text=sprintf("%s (%s)", title, position)
-  tooltip=sprintf("%s\n(%s)", title, player)
-}
-# edge cases to beautify the output
-(player == "tdesktop") && (title ~ /Unknown Track/) {
-  text="telegram voice message"
-}
-
-{
-  system(sprintf("jq -rMnc --arg class \"%s\" --arg text \"%s %s\" --arg tt \"%s\" '{ class: $class, text: $text|@html, tooltip: $tt|@html }'", \
-         status,
-         icon,
-         text,
-         tooltip))
-}
-
-END {}
diff --git a/.config/waybar/modules/mpris.sh b/.config/waybar/modules/mpris.sh
deleted file mode 100755
index 5f5d5c6..0000000
--- a/.config/waybar/modules/mpris.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-
-set -e
-[ -n "$DEBUG" ] && set -x
-
-playerctl -sF metadata -f '"{{artist}}","{{album}}","{{title}}","{{duration(position)}}","{{playerName}}","{{lc(status)}}"' | awk -F',' -f "${HOME}/.config/waybar/modules/mpris.awk"
diff --git a/.config/waybar/modules/timetracked.sh b/.config/waybar/modules/timetracked.sh
deleted file mode 100755
index 4e384bf..0000000
--- a/.config/waybar/modules/timetracked.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/sh
-
-set -e
-[ -n "$DEBUG" ] && set -x
-
-if ! command -v timetrace >/dev/null 2>&1; then
-	exit 0
-fi
-
-case "$1" in
-on-click)
-	timetrace status >/dev/null && timetrace stop
-	exit 0
-	;;
-
-*) ;;
-esac
-
-while true; do
-	timetrace status -o json |
-		jq -c 'if .project == "---" then {} else { text: (["▶", .trackedTimeToday] | join(" ")), class: "timetracked", alt: "timetracked" } end' 2>/dev/null
-	sleep 30
-done
diff --git a/.config/waybar/modules/todo.go b/.config/waybar/modules/todo.go
deleted file mode 100755
index 2692ec9..0000000
--- a/.config/waybar/modules/todo.go
+++ /dev/null
@@ -1,229 +0,0 @@
-#!/usr/bin/env yaegi
-
-// # Documentation
-// we try to read a file pointed to by WAYBAR_TODO_FILE.
-// While no particular format is assumed, we recommend
-// Markdown.
-// We extract the todos from the top-level list items
-// (listings start with a `*` character).
-//
-// # Usage:
-// go build -o waybar-todo todo.go
-package main
-
-import (
-	"bufio"
-	"encoding/json"
-	"log"
-	"os"
-	"os/signal"
-	"regexp"
-  "runtime"
-	"strings"
-	"time"
-
-	"github.com/fsnotify/fsnotify"
-	"golang.org/x/sys/unix"
-)
-
-const (
-	TODO_INACTIVE_STRING string = ""
-	TODO_LABEL_REGEX     string = `\[\[!(.*)\]\]`
-)
-
-var (
-	active      = true
-	todofile    = os.Getenv("WAYBAR_TODO_FILE")
-	cookiefile  = os.ExpandEnv("${XDG_RUNTIME_DIR}/waybar-todo.cookie")
-	labelFilter = os.Getenv("WAYBAR_TODO_FILTER")
-)
-
-func printJson(text, tooltip string, class []string, alt string, percentage int) error {
-	return json.NewEncoder(os.Stdout).Encode(map[string]interface{}{
-		"text":       text,
-		"tooltip":    tooltip,
-		"class":      class,
-		"alt":        alt,
-		"percentage": percentage,
-	})
-}
-
-type todoItem struct {
-	text  string
-	label string
-}
-
-func readTodofile2(path string) ([]todoItem, error) {
-	f, err := os.Open(path)
-	if err != nil {
-		return nil, err
-	}
-	var todos []todoItem
-	for lr := bufio.NewScanner(f); lr.Scan(); {
-		skip := 0
-		switch {
-		case strings.HasPrefix(lr.Text(), "*"):
-			skip = 2
-		case strings.HasPrefix(lr.Text(), "- [ ]"):
-			skip = 6
-		case strings.HasPrefix(lr.Text(), "- [x]"):
-			fallthrough
-		default:
-			continue
-		}
-		ti := todoItem{text: lr.Text()[skip:]}
-		matches := labelre.FindAllStringSubmatch(ti.text, -1)
-		if matches != nil && len(matches) > 0 {
-			ti.label = matches[0][1]
-			ti.text = strings.TrimSpace(
-				strings.Replace(ti.text, matches[0][0], "", 1))
-		}
-		todos = append(todos, ti)
-	}
-	return todos, nil
-}
-
-func setCookie(active bool) error {
-	if !active {
-		_, err := os.Create(cookiefile)
-		return err
-	}
-	return os.Remove(cookiefile)
-}
-
-func update() error {
-	if _, err := os.Stat(cookiefile); err == nil {
-		log.Printf("cookie set, we're inactive")
-		active = false
-	}
-	if !active {
-		return printJson(TODO_INACTIVE_STRING, "* inactive *", []string{"off"}, "off", 0)
-	}
-	todos, err := readTodofile2(todofile)
-	if err != nil {
-		return err
-	}
-	var (
-		text       string
-		tooltip    []string
-		extraClass string
-	)
-	for _, item := range todos {
-		if labelFilter != "" && strings.Contains(labelFilter, item.label) {
-			continue
-		}
-		if text == "" {
-			text = item.text
-			extraClass = item.label
-			continue
-		}
-		// render out the rest of the todos into the tooltip
-		tooltip = append(tooltip, item.text)
-	}
-	return printJson(text, strings.Join(tooltip, "\n"), []string{"on", extraClass}, "on", 1)
-}
-
-var labelre *regexp.Regexp
-
-func init() {
-	labelre = regexp.MustCompile(TODO_LABEL_REGEX)
-}
-
-func main() {
-  runtime.GOMAXPROCS(1)
-
-	var (
-		updateC = make(chan os.Signal, 1)
-		cancelC = make(chan os.Signal, 1)
-	)
-	signal.Notify(updateC, unix.SIGUSR1, unix.SIGUSR2, unix.SIGHUP)
-	signal.Notify(cancelC, unix.SIGTERM, unix.SIGINT)
-
-	var err error
-	// we will receive a SIGTERM if our parent dies
-	err = unix.Prctl(unix.PR_SET_PDEATHSIG, uintptr(unix.SIGTERM), 0, 0, 0)
-	if err != nil {
-		log.Fatalf("error: setting prctl: %v", err)
-	}
-
-	if todofile == "" {
-		panic("missing TODO file")
-		// // get from nb(1)
-		// nb := exec.Command("sh", "-c", "nb show --no-color --path todo")
-		// nb_output, err := nb.Output()
-		// if err != nil {
-		// 	e := err.(*exec.ExitError)
-		// 	log.Fatalf("error: finding todofile via nb: %s", e.Stderr)
-		// }
-		// todofile = strings.TrimSpace(string(nb_output))
-	}
-
-	log.Printf("watching %q", todofile)
-
-	w, err := fsnotify.NewWatcher()
-	if err != nil {
-		log.Fatalf("error: creating watcher: %v", err)
-	}
-	defer w.Close()
-
-	if err := w.Add(todofile); err != nil {
-		log.Fatalf("error: adding watch: %v", err)
-	}
-
-	if err := update(); err != nil {
-		// fail here because it's the first time we
-		// try to read the todofile.
-		log.Fatalf("error: %v", err)
-	}
-	for {
-		select {
-		case evt, ok := <-w.Events:
-			if !ok {
-				return
-			}
-			// see https://github.com/fsnotify/fsnotify/issues/94
-			//     https://github.com/gohugoio/hugo/pull/4720
-			if evt.Op&fsnotify.Remove == fsnotify.Remove {
-				counter := 0
-				for w.Add(todofile) != nil {
-					counter++
-					if counter >= 1000 {
-						log.Panic("error: unable to add file watcher")
-					}
-					time.Sleep(100 * time.Millisecond)
-				}
-			}
-			goto force_update
-		case err, ok := <-w.Errors:
-			if !ok {
-				return
-			}
-			log.Printf("error: from watcher: %v", err)
-
-		case sig := <-updateC:
-			switch sig {
-			case unix.SIGUSR1: // on
-				active = !active
-				if err := setCookie(active); err != nil {
-					log.Printf("err: %v", err)
-				}
-				goto force_update
-			case unix.SIGUSR2: //
-				if strings.Contains(labelFilter, "work") {
-					labelFilter = strings.Trim(strings.ReplaceAll(labelFilter, "work", ""), ",")
-				} else {
-					labelFilter = strings.Join([]string{labelFilter, "work"}, ",")
-				}
-				continue
-			case unix.SIGHUP: // force update
-				log.Println("force update")
-				goto force_update
-			}
-		case <-cancelC:
-			log.Printf("%s exiting", os.Args[0])
-			os.Exit(0)
-		}
-	force_update:
-		_ = update()
-	}
-}
diff --git a/.config/waybar/modules/toggl.lua b/.config/waybar/modules/toggl.lua
deleted file mode 100755
index 7c9f0b9..0000000
--- a/.config/waybar/modules/toggl.lua
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env luajit
-
-TOKEN = os.getenv("TOGGL_TOKEN")
-if not TOKEN then
-    io.stderr:write("need TOGGL_TOKEN\n")
-    os.exit(1)
-end
-
-function timer_duration()
-    cmd = string.format('toggl -t %s -j timer ls | jq -r ".[0].duration"', TOKEN)
-    local f = assert(io.popen(cmd, 'r'))
-    local s = assert(f:read('*a'))
-    f:close()
-    if not (s == '') then
-        return tonumber(s)
-    end
-end
-
-unix_time = os.time()
-
-diff = timer_duration()
-if not diff then
-    os.exit(0)
-end
-
-d = unix_time + diff
-
-print(string.format('%dh %.2dm', d/(60*60), d/60%60))
diff --git a/.config/waybar/modules/vpn.sh b/.config/waybar/modules/vpn.sh
deleted file mode 100755
index c4d50fa..0000000
--- a/.config/waybar/modules/vpn.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/sh
-
-set -e
-[ -n "$DEBUG" ] && set -x
-
-case "$1" in
-toggle) exit 1 ;;
-esac
-
-extern_ip=$(curl -SsfL http://api.ipify.org/?format=text)
-
-vpn_is_up() {
-	case "$extern_ip" in
-	138.201.245.159) return 0 ;; # hetzner node
-	esac
-	return 1
-}
-
-if vpn_is_up; then
-	printf '{"text": "󰒃", "tooltip": "external ip is %s"}\n' "$extern_ip"
-else
-	# printf '{"text": "󰦜", "tooltip": "disconnected"}\n'
-	printf '{}\n'
-fi
diff --git a/.config/waybar/modules/weather.sh b/.config/waybar/modules/weather.sh
deleted file mode 100755
index 929732b..0000000
--- a/.config/waybar/modules/weather.sh
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/sh
-set -e
-[ -n "$DEBUG" ] && set -x
-
-loc=$1
-if [ -z "${loc}" ]; then
-	# use /etc/localtime
-	# loc=$(basename "$(readlink -f /etc/localtime)")
-	loc="${HOME_LAT},${HOME_LON}"
-fi
-
-if [ -n "$REPORT" ]; then
-	curl -s v2.wttr.in/"${loc}"?F | less
-	exit 0
-fi
-
-data="$(curl -s wttr.in/"${loc}"?format=j1)"
-
-class=
-case "$(echo "${data}" | jq -r '.current_condition[].weatherCode')" in
-113) class="sunny" ;;
-116) class="partlycloudy" ;;
-119) class="cloudy" ;;
-122) class="verycloudy" ;;
-143|248|260) class="fog" ;;
-176|263|266|293|296|353) class="lightrain" ;;
-179|182|185|281|284|311|314|317|350|362|365|374|377) class="hail" ;;
-200|386|389|392) class="thunder" ;;
-227|320) class="lightsnow" ;;
-230|329|332|335|338|371|395) class="heavysnow" ;;
-299|302|305|308|356|359): class="heavyrain" ;;
-323|326|368) class="snowrain" ;;
-esac
-
-echo "${data}" | jq \
-	--raw-output \
-	--unbuffered \
-	--compact-output \
-	--arg class "${class}" \
-	--arg tooltip "$(curl -s v2.wttr.in/"${loc}"?ATFQ | tail -n5)" \
-	'.current_condition[] | { text: .weatherDesc[0].value, percentage: (.temp_C | tonumber), class: $class, alt: $class, tooltip: ($tooltip) }'
-