From 6479f9ae5e3e61f9e3d87225b0d52a907c4698ca Mon Sep 17 00:00:00 2001 From: sterni Date: Fri, 20 Dec 2024 01:56:02 +0100 Subject: [PATCH] =?UTF-8?q?feat(sterni/bl=C3=ABrg):=20yet=20another=20blog?= =?UTF-8?q?=20software?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, blërg is an incomplete reimplementation of //users/sterni/mblog that uses mblaze(7) and //users/sterni/mn2html to process the backing mail notes. Now, why start from scratch again? - mblog is depressingly slow at the moment which is due to //third_party/lisp/mime4cl. The performance problems are (probably) solvable, but this would require carefully redesigning the library's use of streams. I'm not motivated to look into that at the moment, unfortunately. - I had an idea for intergrating additional storage backends for entries into an mblog like software. I've found experimenting with this in BQN to be quite pleasant as the backends can easily be expressed as namespaces. Change-Id: I90c8ff7b5f7235d6fd7b0619338b553be8742e49 Reviewed-on: https://cl.tvl.fyi/c/depot/+/13015 Autosubmit: sterni Tested-by: BuildkiteCI Reviewed-by: sterni --- users/sterni/blërg/blërg.bqn | 93 ++++++++++++++++++++++++++++++++++ users/sterni/blërg/default.nix | 32 ++++++++++++ 2 files changed, 125 insertions(+) create mode 100755 users/sterni/blërg/blërg.bqn create mode 100644 users/sterni/blërg/default.nix diff --git a/users/sterni/blërg/blërg.bqn b/users/sterni/blërg/blërg.bqn new file mode 100755 index 000000000..de5986acd --- /dev/null +++ b/users/sterni/blërg/blërg.bqn @@ -0,0 +1,93 @@ +#!/usr/bin/env BQN +# SPDX-FileCopyrightText: Copyright © 2024 sterni +# SPDX-License-Identifier: GPL-3.0-only +# +# blërg is a reimplementation of mblog in BQN. BQN is used as a sort of bespoke +# scripting languages so we can rely on external tools for certain tasks (e.g. +# transforming HTML and parsing MIME messages). +# +# Specifically, blërg depends on: +# - mblaze +# - mn2html +# - execline (to work around the lack of cwd in BQN) + +# Utilities + +MkDirP ← •file.CreateDir⍟(¬•file.Exists) + +AsciiDown ← ('A'-'a')⊸(⊢-×⟜('A'⊸≤∧≤⟜'Z')) + +nl ← @+10 + +SplitChar ← ((=(¯1˙⍟⊣)¨+`∘=)⊔⊢) +Lines ← nl⊸SplitChar + +ReadPosInt ← {(𝕨⊸×+⊣)´∘⌽-⟜'0'𝕩} # ty leah2 +ReadPosDec ← 10⊸ReadPosInt + +ApplyMany ← {fs 𝕊 arg: {𝕏 arg}¨ fs} + +Chomp ← {⟨nl⟩≡¯1↑𝕩? ¯1↓𝕩; 𝕩} + +Run ← { + 𝕊 𝕩: 1 𝕊 𝕩; + doChomp 𝕊 cmd: + exit‿stdout‿stderr ← •SH cmd + •term.ErrRaw⍟(0≠exit) stderr + ⟨Chomp⍟doChomp stdout, exit⟩ +} + +R ← {𝕊 stdout‿exit: !0=exit ⋄ stdout}∘Run +LR ← Lines∘R + +# (Apple) Mail Notes Backend + +# TODO(sterni): avoid argv limit by chunking +Hdr ← {LR "mhdr"‿"-dh"‿𝕨∾𝕩} +Date ← {ReadPosDec¨ LR "mhdr"‿"-Dh"‿"Date"∾𝕩} + +MailNotesBackend ← {𝕊 mailDir: + Filter ← {𝕩 ("com.apple.mail-note"⊸≡¨/⊣) "X-Uniform-Type-Identifier" Hdr 𝕩} + Id ← AsciiDown "X-Universally-Unique-Identifier"⊸Hdr + Title ← "Subject"⊸Hdr + MkRenderer ← {𝕊 p: {R "execline-cd"‿𝕩‿"mshow"‿"-x"‿p ⋄ R "mn2html"‿p}} + # TODO(sterni): entries could become namespaces + Entries ⇐ {𝕊: ⍉>⟨Id,Title,Date,MkRenderer¨⟩⊸ApplyMany Filter LR "mlist"‿mailDir} +} + +# Rendering + +RenderPage ← { +∾" + + + +"‿𝕨‿" + +

"‿𝕨‿"

"‿𝕩 +} + +WriteEntry ← {outDir 𝕊 id‿title‿·‿renderEntry: + entryDir ← MkDirP outDir •file.At id + (entryDir •file.At "index.html") •file.Chars title RenderPage RenderEntry entryDir + # TODO(sterni): urlencode + "
  • "∾title∾"
  • " +} + +# Main + +mailDir‿outDir ← { + # Usage: blërg + ! 2=≠•args + # TODO(sterni): expand ~/ + •wdpath⊸•file.At¨ •args +} + +m ← MailNotesBackend mailDir +entries ← ((⍒ 2⊸⊑˘)⊏⊢) m.Entries @ + +title ← "blërg" + +MkDirP outDir +entryIndex ← (< outDir⊸WriteEntry)˘ entries +(outDir •file.At "index.html") •file.Chars title RenderPage ∾"
      "∾entryIndex∾"
    " diff --git a/users/sterni/blërg/default.nix b/users/sterni/blërg/default.nix new file mode 100644 index 000000000..f329fbdb4 --- /dev/null +++ b/users/sterni/blërg/default.nix @@ -0,0 +1,32 @@ +{ depot, pkgs, lib, ... }: + +let + runtimeDependencies = [ + depot.users.sterni.mn2html + pkgs.mblaze + pkgs.execline # execline-cd + ]; + + buildInputs = [ + pkgs.cbqn + ]; +in + +pkgs.runCommandNoCC "blerg" +{ + src = builtins.path { + name = "blerg.bqn"; + path = ./. + "/blërg.bqn"; + }; + nativeBuildInputs = [ pkgs.buildPackages.makeWrapper ]; + inherit buildInputs; + passthru.shell = pkgs.mkShell { + name = "blërg-shell"; + packages = runtimeDependencies ++ buildInputs; + }; +} + '' + install -Dm755 "$src" "$out/bin/blërg" + patchShebangs "$out/bin/blërg" + wrapProgram "$out/bin/blërg" --prefix PATH : "${lib.makeBinPath runtimeDependencies}" + ''