Add auto compilation of .md and .typ files to filebrowser
This commit is contained in:
@@ -1,12 +1,83 @@
|
||||
{ config, ... }:
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
storageRoot = "/var/lib/filebrowser/files";
|
||||
publishDirName = "_publish";
|
||||
|
||||
fontPackages = with pkgs; [
|
||||
libertinus
|
||||
gyre-fonts
|
||||
];
|
||||
|
||||
processorScript = pkgs.writeShellScriptBin "process-docs" ''
|
||||
SRC_ROOT="${storageRoot}"
|
||||
OUT_ROOT="${storageRoot}/${publishDirName}"
|
||||
|
||||
# Function to compile a single file
|
||||
compile_file() {
|
||||
local file="$1"
|
||||
# Remove SRC_ROOT prefix to get relative path
|
||||
local rel_path="''${file#$SRC_ROOT/}"
|
||||
# Construct target path (swap extension to .pdf)
|
||||
local target="$OUT_ROOT/''${rel_path%.*}.pdf"
|
||||
local target_dir
|
||||
target_dir=$(${pkgs.coreutils}/bin/dirname "$target")
|
||||
|
||||
echo "Processing: $rel_path"
|
||||
${pkgs.coreutils}/bin/mkdir -p "$target_dir"
|
||||
|
||||
echo "Debug: Checking font visibility..."
|
||||
typst fonts
|
||||
|
||||
if [[ "$file" == *.md ]]; then
|
||||
pandoc "$file" -o "$target" --pdf-engine=typst -V mainfont="Libertinus Serif"
|
||||
elif [[ "$file" == *.typ ]]; then
|
||||
typst compile "$file" "$target"
|
||||
fi
|
||||
|
||||
# Ensure filebrowser can read the new file
|
||||
${pkgs.coreutils}/bin/chown filebrowser:filebrowser "$target"
|
||||
}
|
||||
|
||||
export -f compile_file
|
||||
export SRC_ROOT OUT_ROOT
|
||||
|
||||
# 1. Initial Scan: Find all .md/.typ files not inside the export dir
|
||||
# and update them if the source is newer than the target
|
||||
${pkgs.findutils}/bin/find "$SRC_ROOT" -type f \( -name "*.md" -o -name "*.typ" \) \
|
||||
-not -path "$SRC_ROOT/${publishDirName}/*" | while read -r file; do
|
||||
rel="''${file#$SRC_ROOT/}"
|
||||
tgt="$OUT_ROOT/''${rel%.*}.pdf"
|
||||
|
||||
# Only compile if target doesn't exist or source is newer
|
||||
if [ ! -f "$tgt" ] || [ "$file" -nt "$tgt" ]; then
|
||||
compile_file "$file"
|
||||
fi
|
||||
done
|
||||
|
||||
# 2. Watcher Mode
|
||||
echo "Starting watcher on $SRC_ROOT..."
|
||||
# --exclude matches the export dir to prevent infinite loops
|
||||
${pkgs.inotify-tools}/bin/inotifywait -m -r -e close_write,moved_to \
|
||||
--exclude "${publishDirName}" \
|
||||
--format '%w%f' "$SRC_ROOT" | while read -r file; do
|
||||
if [[ "$file" == *.md ]] || [[ "$file" == *.typ ]]; then
|
||||
compile_file "$file"
|
||||
fi
|
||||
done
|
||||
'';
|
||||
|
||||
in
|
||||
{
|
||||
services.filebrowser = {
|
||||
enable = true;
|
||||
|
||||
settings = {
|
||||
root = storageRoot;
|
||||
port = 9876;
|
||||
branding.name = "Jelle's Files";
|
||||
};
|
||||
@@ -15,4 +86,31 @@ in
|
||||
services.caddy.virtualHosts."files.jelles.net".extraConfig = ''
|
||||
reverse_proxy :${toString config.services.filebrowser.settings.port}
|
||||
'';
|
||||
|
||||
systemd.services.pdf-watcher = {
|
||||
description = "Auto-compile MD and Typst to PDF";
|
||||
after = [ "filebrowser.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
# Important: Run as the same user as Filebrowser to avoid permission issues
|
||||
serviceConfig = {
|
||||
User = "filebrowser";
|
||||
Group = "filebrowser";
|
||||
ExecStart = "${processorScript}/bin/process-docs";
|
||||
|
||||
WorkingDirectory = storageRoot;
|
||||
Environment = [
|
||||
"HOME=/var/lib/filebrowser"
|
||||
"XDG_CACHE_HOME=/var/lib/filebrowser/.cache"
|
||||
"TYPST_FONT_PATHS=${lib.makeSearchPath "share/fonts" fontPackages}"
|
||||
];
|
||||
|
||||
Restart = "always";
|
||||
};
|
||||
|
||||
path = with pkgs; [
|
||||
typst
|
||||
pandoc
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user