web -> http

This commit is contained in:
2024-01-26 21:45:22 +01:00
parent 4a5943d61b
commit 2fd65cf9a8
63 changed files with 52 additions and 52 deletions
+118
View File
@@ -0,0 +1,118 @@
{ config, pkgs, lib, mkDomain, flakes, ... }:
let
cfg = config.services.docs-to-host;
# https://pagefind.app/docs/ui-usage/
pagefind-default-ui = ''
<link href="/pagefind/pagefind-ui.css" rel="stylesheet">
<script src="/pagefind/pagefind-ui.js"></script>
<div id="search"></div>
<script>
window.addEventListener('DOMContentLoaded', (event) => {
new PagefindUI({ element: "#search", showSubResults: true });
});
</script>
'';
# TODO: symlink dotfiles to $out
# TODO: ability to set fallback for unknown languages, instead of --force-language en
# TODO: for some reason pagefind is not able to work with symlinks as input. is it a one-file-system restriction?
# TODO: for some reason pagefind requires write access to other files than pagefind/
addPagefindIndex = root: pkgs.runCommand "${root.name}-with-pagefind" {
nativeBuildInputs = [ cfg.pagefind.package pkgs.rsync ];
} ''
#mkdir $out
#cd $out
#ln -s ${root}/* .
# workaround pagefind shortcomings...
mkdir foobar
cd foobar
time rsync -r --chmod +rw --copy-links ${root}/ .
test ! -e pagefind || {
>&2 echo 'ERROR: `root` input has `pagefind` already in it!'
false
}
pagefind --site . --force-language en
mkdir $out
ln -s ${root}/* $out/
cp -a pagefind $out
'';
in
{
options = with lib; {
services.docs-to-host.enable = mkEnableOption (lib.mdDoc "docs-to-host");
services.docs-to-host.pagefind = {
enable = mkEnableOption (lib.mdDoc "pagefind default on index of docs");
package = mkPackageOptionMD flakes.unstable.pkgs "pagefind" { };
};
services.docs-to-host.docs = mkOption {
type = types.listOf (types.submodule {
options = {
dirname = mkOption {
type = types.str;
example = "linux-doc";
description = lib.mdDoc "The relative dirname at which the documentation will be linked";
};
basename = mkOption {
type = types.str;
example = "foobar.html";
default = "";
description = lib.mdDoc "The basename to which the documentation entry will be linked. Not needed if index.html exists.";
};
path = mkOption {
type = types.path;
example = lib.literalExpression "pkgs.fetchzip {...}";
description = lib.mdDoc "The static html documentation to host";
};
desc = mkOption {
type = types.str;
#description = "A short decription about the hosted documentation in markdown.";
description = "A short decription about the hosted documentation.";
};
};
});
default = [ ];
#description = lib.mdDoc ''TODO'';
};
};
# TODO: host man pages (man -H)
config = let
mkLinkFarmEntry = {dirname, path, ...}: {
name = dirname;
path = path;
};
mkRow = {dirname, basename, path, desc}:
''<tr><td><a href="${dirname}/${basename}">${dirname}</a><td>${desc}'';
root = pkgs.linkFarm "docs-html" ([{name = "index.html"; path = pkgs.writeText "docs-index.html" ''
<!DOCTYPE html>
${lib.optionalString cfg.pagefind.enable
pagefind-default-ui
}
<table>
<tr><th>URL<th>Desc
${lib.concatStringsSep "\n" ( builtins.map mkRow cfg.docs ) }
</table>
'';
}] ++ (builtins.map mkLinkFarmEntry cfg.docs));
in {
# i assume we import this if needed
services.docs-to-host.enable = lib.mkDefault true;
services.docs-to-host.pagefind.enable = lib.mkDefault true;
services.nginx.virtualHosts.${mkDomain "docs"} = lib.mkIf cfg.enable {
forceSSL = true; # addSSL = true;
enableACME = true; #useACMEHost = acmeDomain;
root = if cfg.pagefind.enable
then addPagefindIndex root
else root;
};
};
}
+10
View File
@@ -0,0 +1,10 @@
{ config, pkgs, lib, inputs, ... }:
{
services.docs-to-host.docs = [
{
dirname = "home-manager-manual";
path = "${inputs.home-manager.packages.${config.nixpkgs.system}.docs-html}/share/doc/home-manager";
desc = "Home-Manager - a user environment configurator";
}
];
}
+8
View File
@@ -0,0 +1,8 @@
{ config, pkgs, lib, ... }:
{
services.docs-to-host.docs = [{
desc = "Linux kernel html documentation";
dirname = "linux-docs";
path = "${pkgs.linux-doc}/share/doc/linux-doc";
}];
}
+80
View File
@@ -0,0 +1,80 @@
{ config, pkgs, lib, inputs, system, ... }:
let
# https://stackoverflow.com/a/60232211
system = config.nixpkgs.system;
#mk-nixpkgs-manual = input: import "${input}/doc" { pkgs = import input { inherit system; }; };
mk-nixpkgs-manual = input: (import "${input}/pkgs/top-level/release.nix" { nixpkgs = import input { inherit system; }; }).manual;
mk-nixos-manual = input: (import "${input}/nixos/release.nix" { nixpkgs = import input { inherit system; }; }).manualHTML.${system};
in
{
services.docs-to-host.docs = [
{
dirname = "nix-manual";
path = "${pkgs.nix.doc}/share/doc/nix/manual";
desc = "Official Nix manual";
}
{
dirname = "nixpkgs-manual";
basename= "manual.html";
path = "${mk-nixpkgs-manual inputs.nixpkgs}/share/doc/nixpkgs";
desc = "Official Nixpkgs manual";
}
{
dirname = "nixos-manual";
path = "${mk-nixos-manual inputs.nixpkgs}/share/doc/nixos";
desc = "Official Nixos manual";
}
# == Old Nixpkgs manuals ==
/** /
{
dirname = "nixpkgs-manual-22.11";
basename= "manual.html";
path = "${mk-nixpkgs-manual inputs.nixpkgs-22}/share/doc/nixpkgs";
desc = "Official Nixpkgs 22.11 manual";
}
{
dirname = "nixpkgs-manual-21.11";
basename= "manual.html";
path = "${mk-nixpkgs-manual inputs.nixpkgs-21}/share/doc/nixpkgs";
desc = "Official Nixpkgs 21.11 manual";
}
{
dirname = "nixpkgs-manual-20.09";
basename= "manual.html";
path = "${mk-nixpkgs-manual inputs.nixpkgs-20}/share/doc/nixpkgs";
desc = "Official Nixpkgs 20.09 manual";
}
{
dirname = "nixpkgs-manual-19.09";
basename= "manual.html";
path = "${mk-nixpkgs-manual inputs.nixpkgs-19}/share/doc/nixpkgs";
desc = "Official Nixpkgs 19.09 manual";
}
/**/
# == Old Nixos manuals ==
/** /
{
dirname = "nixos-manual-22.11";
path = "${mk-nixos-manual inputs.nixpkgs-22}/share/doc/nixos";
desc = "Official Nixos 22.11 manual";
}
{
dirname = "nixos-manual-21.11";
path = "${mk-nixos-manual inputs.nixpkgs-21}/share/doc/nixos";
desc = "Official Nixos 21.11 manual";
}
{
dirname = "nixos-manual-20.09";
path = "${mk-nixos-manual inputs.nixpkgs-20}/share/doc/nixos";
desc = "Official Nixos 20.09 manual";
}
{
dirname = "nixos-manual-19.09";
path = "${mk-nixos-manual inputs.nixpkgs-19}/share/doc/nixos";
desc = "Official Nixos 19.09 manual";
}
/**/
];
}
+285
View File
@@ -0,0 +1,285 @@
{ config, pkgs, lib, ... }:
let
# pdoc data
pdoc-builtins = [
"builtins"
"os"
"array"
"sys"
"time"
"traceback"
"pathlib"
"itertools"
"functools"
"unittest"
"argparse"
"asyncio"
"textwrap"
"collections"
"configparser"
"concurrent"
"contextlib"
"operator"
"pickle" # TODO: marsmellow or whatever
"copy"
"ctypes"
"pprint"
"shlex"
"re"
"abc"
"ast"
"random"
"shutil"
"sqlite3"
"subprocess"
"statistics"
"string"
"tarfile"
"typing"
"uuid"
"warnings"
"wave"
"dataclasses"
"glob"
"gzip"
"inspect"
"json"
"base64"
"zipfile"
];
pdoc-modules = [
{name="more-itertools"; literal="more_itertools";}
"altair"
"pygal"
"vispy"
#"ggplot"
"seaborn"
"bokeh"
"plotly"
"tabulate"
"wavefile"
"moderngl"
"pydantic"
"typer"
"ptpython"
"colorama"
{name="pyjwt"; literal="jwt";}
"zipp"
"aiofiles"
"aafigure"
"urllib3"
"tesserocr"
"trio"
"starlette"
"pyverilog"
"nixpkgs"
"wavedrom"
"httpx"
"pyquery"
"mpv"
{name="beautifulsoup4"; literal="bs4";}
"hid"
#{name="hidapi"; literal="hid";}
#"sanic" # broken build?
"paramiko"
"pydub"
"aiohttp"
"papermill"
"rtoml"
"redis"
"numpy"
#"domeneshop"
"munch"
"migen"
"amaranth"
"click"
"attrs"
"graphviz"
"baron"
"redbaron"
"fastapi"
"pytest"
#"pyglet" # pyglet.com fails, windows only
#"pygame" # pygame.movie fails on pdoc3, pdoc hangs
"plotly"
"peewee"
"parsel"
"pandas"
#"mutmut" # moved to toplevel from python3Packages
"mlflow"
"meshio"
#"einops" # depends on tensorflow, which is broken ATM
"aiodns"
"json5"
"seaborn"
"matplotlib"
"dash"
"rarfile"
"pyramid"
"pygtail"
"codecov"
"nbconvert"
"humanfriendly"
"pendulum"
"jsonpickle"
"cachetools"
"wrapt"
"lxml"
"chardet"
"yarl"
"frozenlist"
"itsdangerous"
"xmltodict"
{name="cached-property"; literal="cached_property";}
"toolz"
"aioitertools"
"coconut"
"asyncpg" #"aiopg"
{name="libsass"; literal="sass";}
{name="pytorch"; literal="torch";}
#{name="pytorch-lightning"; literal="pytorch_lightning";} # broken build?
{name="pillow"; literal="PIL";}
"trio"
"tqdm"
"rich"
"pudb"
"pony"
"mido"
"jedi"
"h5py"
"atom"
"toml"
{name="pyyaml"; literal="yaml";}
"jinja2"
"requests"
"h5py"
"imageio"
"pygments"
"trimesh"
"shapely"
#"faiss"
#"geomloss"
#"mesh_to_sdf"
#"pyrender"
];
toName = x: if builtins.isString x then x else x.name;
toLiteral = x: if builtins.isString x then x else x.literal;
mkPdoc = use-pdoc3: isBuiltin: pkg: let
description = if isBuiltin
then "builtin"
else pkgs.python3Packages.${toName pkg}.meta.description;
version = if isBuiltin
then "-"
else pkgs.python3Packages.${toName pkg}.version;
homepage = if isBuiltin
then "https://docs.python.org/3/library/${toLiteral pkg}.html"
else pkgs.python3Packages.${toName pkg}.meta.homepage or "-";
doc = pkgs.runCommand "pdoc${if use-pdoc3 then "3" else ""}-${toName pkg}-docs" {
nativeBuildInputs = (if use-pdoc3
then [pkgs.python3Packages.pdoc3]
else [pkgs.python3Packages.pdoc])
++ lib.optional (!isBuiltin) (builtins.getAttr (toName pkg) pkgs.python3Packages);
NAME = toName pkg;
LITERAL = toLiteral pkg;
# TODO: license
# TODO: build html with something better than bash
} ''
( timeout 900s ${if !use-pdoc3
then ''pdoc --no-search --math --no-browser --output-directory $out "$LITERAL"''
else ''pdoc3 --skip-errors --output-dir $out --html "$LITERAL"''
} 2>&1 | tee $LITERAL.log ) || true
mkdir -p $out
cp $LITERAL.log $out
test -f $out/index.html && rm -v $out/index.html
function write {
{ printf "%s" "$@"; echo; } >> $out/index.part-"$LITERAL".html
}
write "<tr>"
if test -f $out/"$LITERAL".html; then
write "<td><a href=\"$LITERAL.html\">$NAME</a>"
elif test -d $out/"$LITERAL"; then
write "<td><a href=\"$LITERAL/\">$NAME</a>"
else
write "<td>$NAME"
fi
write "<td>${version}"
if test -s $out/$LITERAL.log; then
write "<td><a href=\"$LITERAL.log\">log</a>"
else
write "<td>-"
fi
write "<td>${lib.escapeXML description}"
${if homepage == "-" then ''
write "<td>n/a"
'' else ''
write "<td><a href=\"${homepage}\">${homepage}</a>"
''}
write "</tr>"
'';
fallback = pkgs.writeTextDir "index.part-${toLiteral pkg}.html" ''
<tr>
<td>${toLiteral pkg}
<td>${version}
<td>&#10799;
<td>${lib.escapeXML description}
<td>${if homepage == "-" then
"n/a"
else
''<a href="${homepage}">${homepage}</a>''
}
</tr>
'';
in if (builtins.tryEval doc.outPath).success
then doc
else fallback;
mkPdocs = use-pdoc3: pkgs.symlinkJoin {
name = "pdoc-docs";
paths = (map (mkPdoc use-pdoc3 true) pdoc-builtins) ++ (map (mkPdoc use-pdoc3 false) pdoc-modules);
# note: globs are sorted
postBuild = ''
echo "<!DOCTYPE html>" >> $out/index.html
echo "<table><tr><th>name<th>version<th>log<th>description<th>homepage</tr>" >> $out/index.html
cat $out/index.part-*.html >> $out/index.html
rm $out/index.part-*.html
echo "</table>" >> $out/index.html
'';
};
in {
# Pdoc
# Auto-generate API documentation for Python projects.
services.docs-to-host.docs = [
{
dirname = "pdoc-docs";
path = mkPdocs false;
desc = "Documentation for various python modules, generated with pdoc";
}
{
dirname = "pdoc3-docs";
path = mkPdocs true;
desc = "Documentation for various python modules, generated with pdoc3";
}
];
/** /
services.nginx.virtualHosts.${mkDomain "pdoc"} = {
forceSSL = true; # addSSL = true;
enableACME = true; #useACMEHost = acmeDomain;
root = mkPdocs false;
};
services.nginx.virtualHosts.${mkDomain "pdoc3"} = {
forceSSL = true; # addSSL = true;
enableACME = true; #useACMEHost = acmeDomain;
root = mkPdocs true;
};
/**/
}
+15
View File
@@ -0,0 +1,15 @@
{ config, pkgs, lib, inputs, ... }:
{
services.docs-to-host.docs = [
{
dirname = "nginx-manual";
path = "${pkgs.nginx.doc}/share/doc/nginx/en";
desc = pkgs.nginx.meta.description;
}
{
dirname = "postgresql-manual";
path = "${pkgs.postgresql.doc}/share/doc/postgresql/html";
desc = pkgs.postgresql.meta.description;
}
];
}
+12
View File
@@ -0,0 +1,12 @@
{ config, pkgs, lib, ... }:
let
python-versions = lib.attrNames (lib.filterAttrs (k: v: lib.isDerivation v) pkgs.pythonDocs.html);
mkDocsEntry = python-version: {
dirname = "${python-version}";
path = "${builtins.toString pkgs.pythonDocs.html.${python-version}}/share/doc/${python-version}/html";
desc = "Documentation for Python ${pkgs.${python-version}.version}";
};
in
{
services.docs-to-host.docs = builtins.map mkDocsEntry python-versions;
}
+23
View File
@@ -0,0 +1,23 @@
{ config, pkgs, lib, ... }:
let
yagcd = pkgs.fetchzip {
url = "http://hitmen.c02.at/files/yagcd/yagcd.tar.gz";
hash = "sha256-6/0oh7Xvbq1eAk2fCtKU+IXm0FbmgXIwAUjXuUKicus=";
stripRoot = false;
};
in
{
services.docs-to-host.docs = [{
desc = "Yet another Gamecube Documentation";
dirname = "yagcd";
path = "${yagcd}/yagcd";
}];
/** /
services.nginx.virtualHosts.${mkDomain "yagcd"} = {
forceSSL = true; # addSSL = true;
enableACME = true; #useACMEHost = acmeDomain;
root = yagcd;
};
/**/
}