From 85019a5bd728e0efddb88d1dfe724291e63b9a58 Mon Sep 17 00:00:00 2001 From: RGBCube Date: Sun, 8 Jun 2025 17:21:48 +0300 Subject: [PATCH 1/3] nushell: clean up dump module, add dump list --- modules/common/nushell/environment.nu | 157 ++++++++++++++++++-------- 1 file changed, 107 insertions(+), 50 deletions(-) diff --git a/modules/common/nushell/environment.nu b/modules/common/nushell/environment.nu index c555193..a5eb78f 100644 --- a/modules/common/nushell/environment.nu +++ b/modules/common/nushell/environment.nu @@ -28,66 +28,123 @@ def --env mcg [path: path]: nothing -> nothing { jj git init --colocate } -let site_path = glob "~" | path join "projects" "site" +module dump { + def site-path []: nothing -> path { + $env.HOME | path join "Projects" "site" + } -# Edit a thought dump. -def "dump ed" [ - namespace: string # The thought dump to edit. Namespaced using '.', does not include file extension. -]: nothing -> nothing { - let dump_path = $site_path | path join "site" "dump" ...($namespace | split row ".") | $in + ".md" + def dump-path []: nothing -> path { + site-path | path join "site" "dump" + } - mkdir ($dump_path | path parse | get parent) - touch $dump_path + # Convert a thought dump namespace to the filesystem path. + export def to-path []: string -> path { + let namespace = $in - let old_dump_hash = open $dump_path | hash sha256 + dump-path + | path join ...($namespace | split row ".") + | $in + ".md" + } - ^$env.EDITOR $dump_path + # Convert a filesystem path to a thought dump namespace. + export def to-dump []: path -> string { + let path = $in - let dump_size = ls $dump_path | get 0.size - if $dump_size == 0b { - print $"(ansi red)thought dump was emptied(ansi reset)" - dump rm $namespace - } else if $old_dump_hash == (open $dump_path | hash sha256) { - print $"(ansi yellow)thought dump was not changed(ansi reset)" - } else { - print $"(ansi magenta)thought dump was edited(ansi reset)" + print $path (dump-path) + + $path + | path relative-to (dump-path) + | path split + | str join "." + | str substring 0..<-3 + } + + # List all thought dumps that start with the given namespace. + export def list [ + namespace: string = "" + ]: nothing -> table { + let dump_prefix = dump-path | path join ...($namespace | split row ".") + + let dump_parent_contents = glob ($dump_prefix | path parse | get parent | path join "**" "*.md") + let dump_matches = $dump_parent_contents | filter { str starts-with $dump_prefix } + + ls ...$dump_matches | each { + merge { path: $in.name } + | select path size modified + | merge { namespace: ($in.path | to-dump) } + } + } + + # Deploy the thought dumps and thus the website. + export def deploy []: nothing -> nothing { print $"(ansi green)deploying...(ansi reset)" - cd $site_path + cd (site-path) + ./apply.nu + } - jj commit --message $"dump\(($namespace)\): update" - jj bookmark set master --revision @- + # Edit a thought dump. + export def edit [ + namespace: string # The thought dump to edit. Namespaced using '.', does not include file extension. + ]: nothing -> nothing { + let dump_path = $namespace | to-path - [ - { jj git push --remote origin } - { jj git push --remote rad } - { ./apply.nu } - ] | par-each { do $in } + let old_dump_size = try { ls $dump_path } - cd - + mkdir ($dump_path | path parse | get parent) + touch $dump_path + + let old_dump_hash = open $dump_path | hash sha256 + + ^$env.EDITOR $dump_path + + let dump_size = ls $dump_path | get 0.size + if $dump_size == 0b { + print $"(ansi red)thought dump was emptied(ansi reset)" + delete $namespace --existed-before ($old_dump_size != null) + } else if $old_dump_hash == (open $dump_path | hash sha256) { + print $"(ansi yellow)thought dump was not modifier, doing nothing(ansi reset)" + } else { + print $"(ansi magenta)thought dump was edited(ansi reset)" + + let jj_arguments = [ "--repository", (site-path) ] + + jj ...$jj_arguments commit --message $"dump\(($namespace)\): update" + jj ...$jj_arguments bookmark set master --revision @- + + [ + { jj ...$jj_arguments git push --remote origin } + { jj ...$jj_arguments git push --remote rad } + { deploy } + ] | par-each { do $in } + } + } + + # Delete a thought dump. + export def delete [ + namespace: string # The thought dump to edit. Namespaced using '.', does not include file extension. + --existed-before = true + ]: nothing -> nothing { + let dump_path = $namespace | to-path + let parent_path = $dump_path | path parse | get parent + + print $"(ansi red)deleting thought dump...(ansi reset)" + print --no-newline (ansi red) + rm --verbose $dump_path + print --no-newline (ansi reset) + + if (ls $parent_path | length) == 0 { + print $"(ansi red)parent folder is empty, deleting that too...(ansi reset)" + print $"(ansi yellow)other parents will not be deleted, if you want to delete those do it manually(ansi reset)" + rm $parent_path + } + + if $existed_before { + deploy + } else { + print $"(ansi green)the thought dump didn't exist before, so skipping deployment(ansi reset)" + } } } -# Delete a thought dump. -def "dump rm" [ - namespace: string # The thought dump to edit. Namespaced using '.', does not include file extension. -]: nothing -> nothing { - print $namespace - let dump_path = $site_path | path join "site" "dump" ...($namespace | split row ".") | $in + ".md" - let parent_path = $dump_path | path parse | get parent - - print $"(ansi red)deleting thought dump...(ansi reset)" - rm $dump_path - - if (ls $parent_path | length) == 0 { - print $"(ansi red)parent folder is empty, deleting that too...(ansi reset)" - print $"(ansi yellow)other parents will not be deleted, if you want to delete those do it manually(ansi reset)" - rm $parent_path - } - - print $"(ansi green)deploying...(ansi reset)" - - cd $site_path - ./apply.nu - cd - -} +use dump From 9e9cb7e5220c8d910110f5ab093af66bac2c9710 Mon Sep 17 00:00:00 2001 From: RGBCube Date: Sun, 8 Jun 2025 18:10:03 +0300 Subject: [PATCH 2/3] jujutsu: add undo alias --- modules/common/jujutsu.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/common/jujutsu.nix b/modules/common/jujutsu.nix index 05405ec..dbc973d 100644 --- a/modules/common/jujutsu.nix +++ b/modules/common/jujutsu.nix @@ -63,6 +63,8 @@ in { aliases.tug = [ "bookmark" "move" "--from" "closest(@-)" "--to" "closest_pushable(@)" ]; aliases.t = [ "tug" ]; + aliases.u = [ "undo" ]; + revset-aliases."closest(to)" = "heads(::to & bookmarks())"; revset-aliases."closest_pushable(to)" = "heads(::to & ~description(exact:\"\") & (~empty() | merges()))"; From b97f056b00c6b6564a5fc74d06bbd336781f6b33 Mon Sep 17 00:00:00 2001 From: RGBCube Date: Sun, 8 Jun 2025 18:26:57 +0300 Subject: [PATCH 3/3] cinny: init --- hosts/best/cinny.nix | 78 +++++++++++++++++++++++++++++++++++ hosts/best/forgejo.nix | 4 +- hosts/best/matrix/default.nix | 2 +- modules/nginx.nix | 12 +++++- 4 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 hosts/best/cinny.nix diff --git a/hosts/best/cinny.nix b/hosts/best/cinny.nix new file mode 100644 index 0000000..8e99ed1 --- /dev/null +++ b/hosts/best/cinny.nix @@ -0,0 +1,78 @@ +{ config, lib, pkgs, ... }: let + inherit (lib) flip merge; + + fqdn = "cinny.rgbcu.be"; + root = pkgs.cinny; +in { + nixpkgs.overlays = [(self: super: { + cinny-unwrapped = flip self.callPackage {} ({ + lib, + buildNpmPackage, + fetchFromGitHub, + giflib, + python3, + pkg-config, + pixman, + cairo, + pango, + stdenv, + }: + + buildNpmPackage { + pname = "cinny"; + version = "4.8.0"; + + src = fetchFromGitHub { + owner = "RGBCube"; + repo = "cinny"; + rev = "becc5f65820c6bf0d9acf3ddf5519519c3e174ad"; + hash = "sha256-Ym7BzkWjwR+ojP5jGBeHJeH03PZFuiME54RILR7pDqs="; + }; + + npmDepsHash = "sha256-LZLaaFL7vmFos3TCL4brT6gyEpZFjctsag6uH4CQPdI="; + + nativeBuildInputs = [ + python3 + pkg-config + ]; + + buildInputs = [ + pixman + cairo + pango + ] ++ lib.optionals stdenv.hostPlatform.isDarwin [ giflib ]; + + installPhase = '' + runHook preInstall + + cp -r dist $out + + runHook postInstall + ''; + + meta = { + description = "Yet another Matrix client for the web"; + homepage = "https://cinny.in/"; + license = lib.licenses.agpl3Only; + platforms = lib.platforms.all; + }; + }); + })]; + + services.nginx.virtualHosts.${fqdn} = merge config.services.nginx.sslTemplate { + inherit root; + + extraConfig = /* nginx */ '' + rewrite ^/config.json$ /config.json break; + rewrite ^/manifest.json$ /manifest.json break; + + rewrite ^/sw.js$ /sw.js break; + rewrite ^/pdf.worker.min.js$ /pdf.worker.min.js break; + + rewrite ^/public/(.*)$ /public/$1 break; + rewrite ^/assets/(.*)$ /assets/$1 break; + + rewrite ^(.+)$ /index.html break; + ''; + }; +} diff --git a/hosts/best/forgejo.nix b/hosts/best/forgejo.nix index 10398ad..d9ac998 100644 --- a/hosts/best/forgejo.nix +++ b/hosts/best/forgejo.nix @@ -111,9 +111,7 @@ in { }; services.nginx.virtualHosts.${fqdn} = merge config.services.nginx.sslTemplate { - extraConfig = '' - ${config.services.plausible.extraNginxConfigFor fqdn} - ''; + extraConfig = config.services.plausible.extraNginxConfigFor fqdn; locations."/".proxyPass = "http://[::1]:${toString port}"; }; diff --git a/hosts/best/matrix/default.nix b/hosts/best/matrix/default.nix index a32a9e0..7e27ef8 100644 --- a/hosts/best/matrix/default.nix +++ b/hosts/best/matrix/default.nix @@ -7,7 +7,7 @@ port = 8002; wellKnownResponse = data: /* nginx */ '' - ${config.services.nginx.headers} + ${config.services.nginx.headersNoAccessControlOrigin} add_header Access-Control-Allow-Origin * always; default_type application/json; diff --git a/modules/nginx.nix b/modules/nginx.nix index 0bf98ca..87a80fd 100644 --- a/modules/nginx.nix +++ b/modules/nginx.nix @@ -11,15 +11,26 @@ in { }; options.services.nginx.headers = mkConst /* nginx */ '' + proxy_hide_header Access-Control-Allow-Origin; add_header Access-Control-Allow-Origin $allow_origin always; + + ${config.services.nginx.headersNoAccessControlOrigin} + ''; + + options.services.nginx.headersNoAccessControlOrigin = mkConst /* nginx */ '' + proxy_hide_header Access-Control-Allow-Methods; add_header Access-Control-Allow-Methods $allow_methods always; + proxy_hide_header Strict-Transport-Security; add_header Strict-Transport-Security $hsts_header always; + proxy_hide_header Content-Security-Policy; add_header Content-Security-Policy "script-src 'self' 'unsafe-inline' 'unsafe-eval' ${domain} *.${domain}; object-src 'self' ${domain} *.${domain}; base-uri 'self';" always; + proxy_hide_header Referrer-Policy; add_header Referrer-Policy no-referrer always; + proxy_hide_header X-Frame-Options; add_header X-Frame-Options DENY always; ''; @@ -52,7 +63,6 @@ in { https "max-age=31536000; includeSubdomains; preload"; } - # FIXME: These two aren't working. map $http_origin $allow_origin { ~^https://.+\.${domain}$ $http_origin; }