Tidrapporter med ledger

Jag har ju en förkärlek till att göra saker dels krångliga, men även att göra dem krångligare med hjälp av Emacs. Nu har jag äntligen hittat ett sätt att blanda in ytterligare ett steg i kedjan, nämligen ledger!

Jag för min tiddagbok för jobbet med hjälp av en textfil som tolkas av programmet ledger, som i sin tur rapporterar på lite olika sätt. Formatet är jätteenkelt, i princip:

i 2019-08-23 08:00:00 Agio:InternTid
o 2019-08-23 12:00:00

Ovan är också en ren lögn – jag är aldrig på jobbet så tidigt! Men ovan är att jag kom in vid 08:00:00 och startade med något internt för jobbet, och gick på lunch vid 12. Jag behöver inte fördefiniera några kunder eller kostnadsställen, utan jag fyller bara på. Formatet är tekniskt sett inte ett rent ledger-format, men ledger har arbetat in stöd för det ändå.

Men, för att göra livet lite lättare skrev jag lite elisp, se nedan. Står jag i en buffer där major-mode är satt till ledger-mode så kallar jag bara på den interaktiva funktionen monotux/check-in och svarar på frågorna, så infogas svaren längst ner i filen. Koden är inte vacker, Men Den Funkar Bra Nog(tm) så vi kör på den!

(defun monotux/get-timeclock-candidates (buffer)
  "Extracts available payee candidates from provided BUFFER."
  (let ((regex-payee "^i [0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} [0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\} \\(.*\\)$"))
    (monotux/re-seq regex-payee buffer)))

(defun monotux/check-in ()
  "Checka in på jobbet!"
  (interactive)
  (when (derived-mode-p 'ledger-mode)
    (let* ((pbuf (current-buffer))
           (clock-in-time (concat (read-string "När kom du till jobbet? (HH:MM) ") ":00"))
           (current-date (format-time-string "%Y-%m-%d"))
           complete-line)
      (dolist (e `("i" ,current-date ,clock-in-time))
        (add-to-list 'complete-line e t))
      (let* ((payee-candidates (monotux/get-timeclock-candidates (buffer-string)))
             (payee-chosen (completing-read "Vilket konto? " payee-candidates)))
        (add-to-list 'complete-line payee-chosen t))
      (goto-char (point-max))
      (insert (concat "\n" (string-join complete-line " ") "\n")))))

(defun monotux/check-out ()
  "Checka ut också."
  (interactive)
  (when (derived-mode-p 'ledger-mode)
    (let ((clock-out-time (concat (read-string "När checkade du ut? (HH:MM) ") ":00"))
          (current-date (format-time-string "%Y-%m-%d"))
          complete-line)
      (dolist (e `("o" ,current-date ,clock-out-time))
        (add-to-list 'complete-line e t))
      (goto-char (point-max))
      (insert (concat (string-join complete-line " ") "\n")))))

För att sammanställa en veckorapport av min tid kan en använda en kommandorad som nedan:

$ ledger -f time.ledger --daily --period "this week" reg
19-Aug-23 - 19-Aug-23    (Agio:InternTid)       4.00h     4.00h

Det roliga kommer givetvis när en har fler rapporter över fler dagar. Men det lämnas som en övning för läsaren att sammanställa själv! 🙂

ortholife

Iris till vänster, XD75re till höger

Ortolinjära (ortholinear) tangentbord har blivit lite utav en grej i tangentbordssfären sista åren. Idén är att bygga bort en teknisk rest från skrivmaskinernas tid och sätta alla tangenter i ett rutnät, vilket då ska göra det mer naturligt att skriva på. Fingrarna ska då röra sig uppåt och neråt i respektive kolumn (vänsterlillfinger hanterar då q, a och z då de sitter rakt i en kolumn) snarare än i sidled plus uppåt och neråt, som på ett vanligt tangentbord. Det ska bli mer ergonomiskt.

Hela idén om att det skulle vara mer ergonomiskt är givetvis trams. De ergonomiska problemen med ett tangentbord är många och helt andra än huruvida fingrarna rör sig vertikalt eller lite hur som.

Den gissningsvis enskilt mest populära modellen av denna typ av tangentbord är Planck, döpt efter någon gammal fysiker. En Planck har 12 tangenter per rad, fyra rader och totalt 48 tangenter. Ett normalstort tangentbord har 108 tangenter. Ditt laptoptangentbord har gissningsvis ca 80 tangenter. Planck har 48. Tangentbordet till vänster i bild, mitt Iris, har 54. Tangentbordet till höger har 75.

Antalet tangenter blir intressant för den som vill göra allt det där vanliga med sitt tangentbord. Har du 48 tangenter har du det vanliga alfabetet plus några knappar till för det mest nödvändiga – men ingen sifferrad, inga funktionstangenter, inga piltangenter. Nästan inget mer alls, faktiskt.

Här är även tjusningen – få allt att fungera på ett rimligt vis! Nyckeln är egentligen inte särskilt konstig, det är som hur det fungerar på en laptop – trycker jag på F1 stängs ljudet av på min dator. Trycker jag på F1 med FN-knappen nertryckt blir det ett vanligt F1 som trycks ner. Trycker jag på alt gr och 7 får jag en måsvinge ({). Principen kallas inom tangentbordsvärlden för lager, att vi ”byter” lager när vi trycker in FN-knappen.

Men, på en Planck kan vi programmera tangentbordet och har en väldigt stor frihet att utforma vad som händer. Vi kan ha nästan hur många lager som helst. Tryck in FN1 och vänstra sidan av ditt tangentbord förvandlas till sifferdelen av ett normalt tangentbord. Tryck in FN2 och samma del är istället en samling programmeringstecken. Tryck in både FN1 och FN2 och du tas till ett tredje lager, där ditt tangentbord plötsligt låtsas vara en mus och styrs av tangenttryckningar. Tryck på Q-knappen i detta kombinerade lager och din epost-signatur skrivs ut automagiskt (den här sista är väldigt användbar för mig!).

Problemen kommer när det ska tryckas in control, alt eller shift och ett tecken till, som kanske lever på sifferlagret. Då behöver alla lager planeras, implementeras och testas. Ofta blir det fel, men det är ju här det roliga bor!

24/5 – Utdraget

Ytterligare en dagboksbild. Här står jag på uppfarten till en (numera) riven bro nära gropen.

Gropen visade sig dock vara hungrig, och numera har stängslet ätit upp hela området upp till vägkanten på E10:an. Stora delar av min promenadväg till jobbet har fått läggas om.

Hackigt hemmanät

Vi har bråkat lite med vår bredbandsleverantör (haha, Comhem!) på sistone och beslutat att vi inte vill vara kund hos dem mer. Tyvärr finns ingen annan leverantör i huset (Telia har haft huset ”under installation” sedan 2007), så vi föll tillbaka på 4G då vi har rätt bra förutsättningar för det.

Problemet är bara att någon bestämde sig för att inte använda ett vanligt 4G-modem, utan ville Göra Det Själv.

Så en minidator (Asus Tinkerboard S) fanns redan hemma, ett modem och en trådlös basstation behövde inhandlas. Modemet blev ett Huawei E3372 (se tidigare post här om modemet) och routern blev en Netgear R7500 mest p.g.a. fanns begagnad och relativt billig. udev-reglerna från föregående inlägg gick dock att återanvända.

Då jag inte använt iptables för att dirigera paket på ett tag (nftables-hacket förra året räknas inte!) blev det nästan som en pinsam kalldusch att genomföra projektet – hur gjorde en ens? Dessutom var det hejdlöst drygt att ladda ner paketberoenden på min laptop, skicka till enkortsdatorn och installera, upptäcka att fler paket behövdes och så vidare.

När alla paket och paketberoenden väl var på plats konfigurerade jag upp modemet med en network-manager-profil (nmtui var hjälpsamt här, sedan behövde jag komplettera konfigurationsfilen med en pin-kod) och upptäckte att network-manager har dispatcher-skript en kan använda. Nedan är ett skript jag stal från techytalk.info:

#!/bin/bash
 
IF=$1
STATUS=$2

# ppp0 var aktuellt för mig, ändra annars här
if [ "$IF" == "ppp0" ]
then
    case "$2" in
        up)
        logger -s "ppp0 up, create a masquerade party!"
        echo 1 > /proc/sys/net/ipv4/ip_forward
        /sbin/iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
        /sbin/iptables -A FORWARD -i ppp0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
        /sbin/iptables -A FORWARD -i eth0 -o ppp0 -j ACCEPT
        ;;
        down)
        logger -s "ppp0, too lazy to remove iptables rules"
        echo 0 > /proc/sys/net/ipv4/ip_forward
        ;;
        pre-up)
        logger -s "NM Script pre-up triggered"
        ;;
        post-down)
        logger -s "NM Script post-down triggered"
        ;;
        *)
        ;;
    esac
fi

Sparade ett liknande skript i /etc/NetworkManager/dispatcher.d/ och gjorde det exekverbart. Att jag inte inkluderat några fler regler än NAT-översättningen är för att modemet just nu agerar brandvägg och gör sin egen NAT-översättning. Det ska gå att byta firmware på modemet men jag har inte haft möjlighet än.

Avslutade med att lägga in en dnsmasq som delar ut IP-adresser samt hanterar DNS-frågor. Kastade även in en pihole-liknande reklam- och spårningsblockering redan i brandväggen.

Pythonhack och NixOS

Jag hackade nyligen ihop ett program som läser in ett API och presenterar detta som en ATOM/RSS-feed. Det blev inte snyggt, men nu kan jag följa en blogg som normalt saknar ett RSS-flöde i min RSS-läsare.

Det trixigaste var att lyckas förstå hur en kör ett program som detta i NixOS, men utan att behöva stöka allt för mycket. Jag ville att skriptet ska köras varje timme och jag ville använda några förpaketerade paketberoenden. I korthet, Nix-Writers fixade biffen!

{ pkgs, ... }:
let
  python-hack = pkgs.writers.writePython3 "pythonhack" {
    libraries = [ pkgs.python3Packages.feedgen pkgs.python3Packages.requests ];
  } (builtins.readFile "/path/to/script.py");
in {
  systemd.services.python-hack = {
    description = "hack hack hack";
    serviceConfig = {
      Type = "oneshot";
      User = "foobar";
      ExecStart = python-hack; # samma namn som i let-blocket
    };
  };
  systemd.timers.python-hack = {
    wantedBy = [ "timers.target" ];
    partOf = [ "python-hack.service" ];
    timerConfig.OnCalendar = "hourly";
  };
}

Det är nog lite hackigt att använda writers-funktionaliteten såhär, det är nog tänkt att användas för att skriva programkod direkt i nix-filen, istället för att bara läsa in källkoden från en fil som här ovan. Men det fungerade, och det var relativt enkelt att sätta ihop.

Huawei E3372 & Linux

Det här är mest en anteckning till den framtida Oscar, och eventuella andra intresserade.

Jag har ett USB-modem jag använder med mina datorer hemma, ett Huawei E3372. Det startar först upp som en CD-enhet för att dela med sig av sina drivrutiner, och behöver sedan instrueras att byta läge till ett vanligt modem.

För detta skapade jag en udev-regel som gör det jobbet åt mig, ersätt sökvägar med vad som är korrekt för din Linux:

ATTR{idVendor}=="12d1", ATTR{idProduct}=="14fe", RUN+="${pkgs.usb_modeswitch}/bin/usb_modeswitch -v 12d1 -p 14fe -V 12d1 -P 1506 -J"

Du kommer behöva programmet usb_modeswitch, som verkar finnas paketerad för de flesta distros.

Alla ID:n och liknande fås av att köra en lsusb. Innan modemet bytt läge:

Bus 002 Device 016: ID 12d1:14dc Huawei Technologies Co., Ltd.

Efter att den bytt läge:

Bus 001 Device 006: ID 12d1:1506 Huawei Technologies Co., Ltd. Modem/Networkcard

För mig startade inte modem-manager (som krävs, och är en del av network-manager) automagiskt, så jag lade till en extra udev-regel för att fixa detta när modemet (i rätt läge) ansluts:

ATTR{idVendor}=="12d1", ATTR{idProduct}=="1506", RUN+="${pkgs.systemd}/bin/systemctl restart modem-manager.service"

Nu behöver jag bara be network-manager att koppla upp sig på 4G. Klart!

Ringtestning

Jag gissar att samma problem lär uppkomma under polarnatten. Det är inte konstigt att folk inte är bekanta med polarnätter och midnattssolen, men åtminstone någon som inte är en junior testare borde veta något om att dagslängd förändras under året och att löjliga edge cases borde testas här.

1/2

Hittat i arkivet. Jag tror personen på bilden stannade upp i hopp om att inte kliva in och förstöra bilden, istället stannade hen upp och gjorde bilden. Det tackar vi för.

19/5

Is och foppatofflor

Det är fortfarande något banalt och exotiskt med varm sol och kall is vid samma tillfälle. Det är något fint med att känna sig lite äventyrlig vid byte till sommardäck redan i mitten på maj. Det är även något tungt att inte få känna doften av blommande syren i skymningen.

14/3

Det här ansiktet återkommer lite överallt här i Kiruna. Ibland är hen glad, ibland ledsen. Jag tänkte fortsätta leta och avbilda detta ansikte, tror jag kommer kalla hen Alex.