From 48a837a91959efbc7da7f98447c50f32b4ee7c94 Mon Sep 17 00:00:00 2001
From: Collin Williams <96917990+bluedragon1221@users.noreply.github.com>
Date: Thu, 2 Apr 2026 16:18:29 -0500
Subject: jta, other changes
---
modules/services/nixos/default.nix | 3 +-
modules/services/nixos/jta/default.nix | 49 ++++++++++
modules/services/nixos/jta/go.mod | 5 +
modules/services/nixos/jta/go.sum | 2 +
modules/services/nixos/jta/index.html | 129 +++++++++++++++++++++++++
modules/services/nixos/jta/main.go | 95 ++++++++++++++++++
modules/services/nixos/jta/md_template.html | 11 +++
modules/services/nixos/jta/pkg.nix | 6 ++
modules/services/nixos/jta/style.css | 143 ++++++++++++++++++++++++++++
modules/services/nixos/openssh.nix | 2 +-
modules/services/options.nix | 5 +
modules/terminal/hjem/programs/broot.nix | 33 +++++--
12 files changed, 474 insertions(+), 9 deletions(-)
create mode 100644 modules/services/nixos/jta/default.nix
create mode 100644 modules/services/nixos/jta/go.mod
create mode 100644 modules/services/nixos/jta/go.sum
create mode 100644 modules/services/nixos/jta/index.html
create mode 100644 modules/services/nixos/jta/main.go
create mode 100644 modules/services/nixos/jta/md_template.html
create mode 100644 modules/services/nixos/jta/pkg.nix
create mode 100644 modules/services/nixos/jta/style.css
(limited to 'modules')
diff --git a/modules/services/nixos/default.nix b/modules/services/nixos/default.nix
index d0e170c..32efb1c 100644
--- a/modules/services/nixos/default.nix
+++ b/modules/services/nixos/default.nix
@@ -8,9 +8,8 @@
./btopweb.nix
./cgit
+ ./jta
./polaris.nix
- # ./mopidy.nix
- # ./jellyfin.nix
./agate.nix
./minecraft.nix
./copyparty.nix
diff --git a/modules/services/nixos/jta/default.nix b/modules/services/nixos/jta/default.nix
new file mode 100644
index 0000000..c1ea012
--- /dev/null
+++ b/modules/services/nixos/jta/default.nix
@@ -0,0 +1,49 @@
+{
+ pkgs,
+ config,
+ lib,
+ ...
+}: let
+ cfg = config.collinux.services.jta;
+
+ package = pkgs.callPackage ./pkg.nix {};
+in {
+ imports = [
+ (import ../mkCaddyCfg.nix cfg)
+ ];
+
+ config = lib.mkIf cfg.enable {
+ users.groups."jta" = {};
+ users.users."jta" = {
+ isSystemUser = true;
+ group = "jta";
+ extraGroups = ["fileserver"];
+
+ home = "/var/lib/jta";
+ createHome = true;
+ homeMode = "755";
+ };
+
+ systemd.services."jta" = {
+ description = "Juksere trives aldri, kids";
+ restartIfChanged = true;
+ wants = ["network-online.target" "caddy.service"];
+ after = ["network-online.target" "caddy.service"];
+
+ environment = {
+ PORT = toString cfg.port;
+ ROOT_DIR = "/media/jta";
+ };
+
+ serviceConfig = {
+ User = "jta";
+ Type = "simple";
+
+ WorkingDirectory = "/var/lib/jta";
+ ExecStart = "${package}/bin/jta";
+ };
+
+ wantedBy = ["multi-user.target"];
+ };
+ };
+}
diff --git a/modules/services/nixos/jta/go.mod b/modules/services/nixos/jta/go.mod
new file mode 100644
index 0000000..8f27af1
--- /dev/null
+++ b/modules/services/nixos/jta/go.mod
@@ -0,0 +1,5 @@
+module git.ganymede/jta
+
+go 1.25.5
+
+require github.com/yuin/goldmark v1.8.2
diff --git a/modules/services/nixos/jta/go.sum b/modules/services/nixos/jta/go.sum
new file mode 100644
index 0000000..6a37955
--- /dev/null
+++ b/modules/services/nixos/jta/go.sum
@@ -0,0 +1,2 @@
+github.com/yuin/goldmark v1.8.2 h1:kEGpgqJXdgbkhcOgBxkC0X0PmoPG1ZyoZ117rDVp4zE=
+github.com/yuin/goldmark v1.8.2/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
diff --git a/modules/services/nixos/jta/index.html b/modules/services/nixos/jta/index.html
new file mode 100644
index 0000000..fd93de6
--- /dev/null
+++ b/modules/services/nixos/jta/index.html
@@ -0,0 +1,129 @@
+
+
+
+
+
+ jta@ganymede
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/services/nixos/jta/main.go b/modules/services/nixos/jta/main.go
new file mode 100644
index 0000000..3e5fc1f
--- /dev/null
+++ b/modules/services/nixos/jta/main.go
@@ -0,0 +1,95 @@
+package main
+
+import (
+ "bytes"
+ _ "embed"
+ "html/template"
+ "net/http"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/yuin/goldmark"
+ "github.com/yuin/goldmark/extension"
+)
+
+// Configure Goldmark with GitHub Flavored Markdown
+var mdParser = goldmark.New(
+ goldmark.WithExtensions(
+ extension.GFM,
+ ),
+)
+
+//go:embed md_template.html
+var mdTemplate string
+
+//go:embed style.css
+var styleCSS string
+
+//go:embed index.html
+var indexHTML string
+
+var pageTmpl = template.Must(template.New("md_template.html").Parse(mdTemplate))
+
+func serveMarkdown(w http.ResponseWriter, r *http.Request) {
+ // Prevent path traversal
+ clean := filepath.Clean(r.URL.Path)
+ path := filepath.Join(rootDir, strings.TrimPrefix(clean, "/"))
+
+ mdBytes, err := os.ReadFile(path)
+ if err != nil {
+ http.NotFound(w, r)
+ return
+ }
+
+ var buf bytes.Buffer
+ if err := mdParser.Convert(mdBytes, &buf); err != nil {
+ http.Error(w, "failed to render markdown", 500)
+ return
+ }
+
+ w.Header().Set("Content-Type", "text/html; charset=utf-8")
+
+ pageTmpl.Execute(w, map[string]template.HTML{
+ "Content": template.HTML(buf.String()),
+ })
+}
+
+var rootDir = "."
+
+func main() {
+ if envRootDir := os.Getenv("ROOT_DIR"); envRootDir != "" {
+ rootDir = envRootDir
+ }
+
+ fs := http.FileServer(http.Dir(rootDir))
+ port := os.Getenv("PORT")
+ if port == "" {
+ port = "8080"
+ }
+
+ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
+ if r.URL.Path == "/" || r.URL.Path == "/index.html" {
+ w.Header().Set("Content-Type", "text/html; charset=utf-8")
+ w.Write([]byte(indexHTML))
+ return
+ }
+
+ if r.URL.Path == "/style.css" {
+ w.Header().Set("Content-Type", "text/css; charset=utf-8")
+ w.Write([]byte(styleCSS))
+ return
+ }
+
+ // Intercept markdown files
+ if strings.HasSuffix(r.URL.Path, ".md") {
+ serveMarkdown(w, r)
+ return
+ }
+
+ // Otherwise serve normally
+ fs.ServeHTTP(w, r)
+ })
+
+ http.ListenAndServe(":"+port, nil)
+}
diff --git a/modules/services/nixos/jta/md_template.html b/modules/services/nixos/jta/md_template.html
new file mode 100644
index 0000000..daa57b7
--- /dev/null
+++ b/modules/services/nixos/jta/md_template.html
@@ -0,0 +1,11 @@
+
+
+
+
+ JTA
+
+
+
+ {{.Content}}
+
+
diff --git a/modules/services/nixos/jta/pkg.nix b/modules/services/nixos/jta/pkg.nix
new file mode 100644
index 0000000..c8f7d77
--- /dev/null
+++ b/modules/services/nixos/jta/pkg.nix
@@ -0,0 +1,6 @@
+{pkgs ? import {system = "x86_64-linux";}, ...}:
+pkgs.buildGoModule {
+ name = "jta";
+ src = ./.;
+ vendorHash = "sha256-aeJYO52ALbGxyTFPw6eGCmPlmuCvbXEoX9gcXatN29E=";
+}
diff --git a/modules/services/nixos/jta/style.css b/modules/services/nixos/jta/style.css
new file mode 100644
index 0000000..1d52d19
--- /dev/null
+++ b/modules/services/nixos/jta/style.css
@@ -0,0 +1,143 @@
+:root {
+ --bg: #0f172a;
+ --card: #1e293b;
+ --accent: #22c55e;
+ --text: #e2e8f0;
+ --text-soft: #cbd5e1;
+ --muted: #94a3b8;
+ --border: #334155;
+
+ --font-body: "Avenir Next", "Segoe UI", "Noto Sans", "Helvetica Neue", sans-serif;
+ --font-heading: "Iowan Old Style", "Palatino Linotype", "Book Antiqua", Palatino, serif;
+ --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
+
+ --step--1: clamp(0.88rem, 0.86rem + 0.12vw, 0.96rem);
+ --step-0: clamp(1rem, 0.98rem + 0.16vw, 1.08rem);
+ --step-1: clamp(1.14rem, 1.08rem + 0.26vw, 1.28rem);
+ --step-2: clamp(1.3rem, 1.2rem + 0.45vw, 1.56rem);
+ --step-3: clamp(1.7rem, 1.45rem + 1.1vw, 2.25rem);
+}
+
+/* Base layout */
+body {
+ font-family: var(--font-body);
+ font-size: var(--step-0);
+ background: var(--bg);
+ color: var(--text);
+ max-width: 850px;
+ margin: 2rem auto;
+ padding: 1.5rem;
+ line-height: 1.7;
+ text-rendering: optimizeLegibility;
+}
+
+/* Headings */
+h1 {
+ font-family: var(--font-heading);
+ font-size: var(--step-3);
+ line-height: 1.15;
+ font-weight: 700;
+ letter-spacing: -0.02em;
+ text-align: center;
+ margin: 0 0 1.25rem;
+}
+
+h2 {
+ font-family: var(--font-heading);
+ margin-top: 2.25rem;
+ margin-bottom: 0.75rem;
+ font-size: var(--step-2);
+ line-height: 1.25;
+ letter-spacing: -0.01em;
+}
+
+h3 {
+ font-family: var(--font-heading);
+ margin-top: 1.5rem;
+ margin-bottom: 0.6rem;
+ font-size: var(--step-1);
+ line-height: 1.3;
+ color: var(--text-soft);
+}
+
+/* Text */
+p {
+ color: var(--text);
+ margin-bottom: 1rem;
+ max-width: 65ch;
+}
+
+/* Ordered list (questions) */
+ol {
+ padding-left: 1.2rem;
+ max-width: 65ch;
+}
+
+/* Answer list */
+ul {
+ list-style: none;
+ padding-left: 1.2rem;
+ max-width: 65ch;
+}
+
+ul li {
+ display: flex;
+ align-items: flex-start;
+ gap: 0.6rem;
+ padding: 0.35rem 0.4rem;
+ border-radius: 8px;
+ transition: background 0.15s ease;
+}
+
+/* Checkbox styling */
+input[type="checkbox"] {
+ accent-color: var(--accent);
+ transform: scale(1.2);
+ margin-top: 0.2rem;
+ pointer-events: none;
+}
+
+/* Correct answers */
+li:has(input[type="checkbox"]:checked) {
+ color: #86efac;
+ font-weight: 500;
+}
+
+/* Code blocks */
+pre {
+ font-family: var(--font-mono);
+ font-size: var(--step--1);
+ line-height: 1.6;
+ background: #020617;
+ padding: 1rem;
+ border-radius: 10px;
+ overflow-x: auto;
+ margin: 1rem 0;
+ max-width: 65ch;
+}
+
+code {
+ font-family: var(--font-mono);
+ font-size: 0.95em;
+ background: #020617;
+ padding: 2px 6px;
+ border-radius: 6px;
+}
+
+/* Links */
+a {
+ color: #93c5fd;
+ text-decoration-line: underline;
+ text-decoration-thickness: 2px;
+ text-underline-offset: 0.14em;
+ text-decoration-color: rgba(147, 197, 253, 0.45);
+}
+
+a:hover {
+ text-decoration-color: currentColor;
+}
+
+/* Optional: make everything feel tighter and nicer */
+* {
+ box-sizing: border-box;
+}
diff --git a/modules/services/nixos/openssh.nix b/modules/services/nixos/openssh.nix
index 2d0c45c..1ce1abc 100644
--- a/modules/services/nixos/openssh.nix
+++ b/modules/services/nixos/openssh.nix
@@ -18,7 +18,7 @@ in {
services.openssh = {
enable = true;
- allowSFTP = false;
+ allowSFTP = true;
hostKeys = [
{
diff --git a/modules/services/options.nix b/modules/services/options.nix
index 0484b6b..bb43180 100644
--- a/modules/services/options.nix
+++ b/modules/services/options.nix
@@ -109,6 +109,11 @@ in {
default_port = 8076;
};
+ jta = webserviceOptions {
+ service_name = "jta";
+ default_port = 8072;
+ };
+
copyparty =
(webserviceOptions {
service_name = "copyparty";
diff --git a/modules/terminal/hjem/programs/broot.nix b/modules/terminal/hjem/programs/broot.nix
index d382cbe..8678551 100644
--- a/modules/terminal/hjem/programs/broot.nix
+++ b/modules/terminal/hjem/programs/broot.nix
@@ -13,12 +13,20 @@
default_flags = "-g";
icon_theme = "nerdfont";
- special_paths."~/.config".show = "always";
+ special_paths = {
+ "~/ganymede" = {
+ show = "never";
+ list = "never";
+ sum = "never";
+ };
+ "~/.config".show = "always";
+ };
verbs = [
{
- name = "open-code";
+ name = "edit";
key = "enter";
+ invocation = "e";
execution = "$EDITOR +{line} {file}";
working_dir = "{root}";
apply_to = "file";
@@ -27,17 +35,22 @@
{
name = "lazygit";
key = "ctrl-g";
+ invocation = "lazygit";
execution = "lazygit";
working_dir = "{root}";
- apply_to = "any";
+ leave_broot = false;
+ }
+ {
+ invocation = "opencode {extraargs}";
+ execution = "opencode {extraargs}";
+ working_dir = "{root}";
leave_broot = false;
}
{
name = "justfile";
key = "ctrl-j";
- execution = "${pkgs.just}/bin/just --choose";
+ execution = ''just --choose --chooser "fzf --height=25% --color=bg:-1 --preview 'just --show {}'"'';
working_dir = "{root}";
- apply_to = "any";
leave_broot = false;
}
{
@@ -48,7 +61,15 @@
leave_broot = false;
}
{
- name = "home";
+ key = "alt-enter";
+ execution = "swaymsg exec -- foot -D '{root}' fish -c 'br'";
+ leave_broot = false;
+ }
+ {
+ key = "ctrl-a";
+ internal = "toggle_stage";
+ }
+ {
key = "ctrl-h";
cmd = ":input_clear;:focus ~";
}
--
cgit v1.3.1