From 90b46d44f10d9fc330d2d98d3784b4662dd10252 Mon Sep 17 00:00:00 2001 From: Lain Iwakura Date: Tue, 19 May 2026 22:36:24 +0300 Subject: [PATCH] feat: initial --- .gitignore | 1 + flake.lock | 27 ++++++++++++++++++++++ flake.nix | 55 ++++++++++++++++++++++++++++++++++++++++++++ go.mod | 3 +++ main.go | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ web/index.html | 21 +++++++++++++++++ web/style.css | 58 ++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 227 insertions(+) create mode 100644 .gitignore create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 go.mod create mode 100644 main.go create mode 100644 web/index.html create mode 100644 web/style.css diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b2be92b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +result diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..6898726 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1779102034, + "narHash": "sha256-vZJZjLo513IeI8hjzHFc6TDezUd4uCE2Eq4SNO3DNNg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "687f05a9184cad4eaf905c48b63649e3a86f5433", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-25.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..a1f6e03 --- /dev/null +++ b/flake.nix @@ -0,0 +1,55 @@ +{ + description = "cultist.club landing page"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11"; + }; + + outputs = { self, nixpkgs }: + let + systems = [ + "x86_64-linux" + "aarch64-darwin" + ]; + forAllSystems = nixpkgs.lib.genAttrs systems; + in + { + packages = forAllSystems (system: + let + pkgs = import nixpkgs { inherit system; }; + cultist-website = pkgs.buildGoModule { + pname = "cultist-website"; + version = "0.1.0"; + src = ./.; + vendorHash = null; + nativeBuildInputs = [ pkgs.makeWrapper ]; + ldflags = [ "-s" "-w" ]; + postInstall = + if pkgs.stdenv.hostPlatform.isLinux then + '' + wrapProgram $out/bin/cultist-website \ + --prefix PATH : ${pkgs.lib.makeBinPath [ pkgs.procps ]} + '' + else + ""; + }; + in + { + default = cultist-website; + cultist-website = cultist-website; + }); + + apps = forAllSystems (system: { + default = { + type = "app"; + program = "${self.packages.${system}.default}/bin/cultist-website"; + }; + }); + + devShells = forAllSystems (system: { + default = import nixpkgs { inherit system; }.mkShell { + packages = [ (import nixpkgs { inherit system; }).go ]; + }; + }); + }; +} \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..1f2ee54 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module cultist.club/website + +go 1.25.9 \ No newline at end of file diff --git a/main.go b/main.go new file mode 100644 index 0000000..79e79e4 --- /dev/null +++ b/main.go @@ -0,0 +1,62 @@ +package main + +import ( + "embed" + "html" + "io/fs" + "log/slog" + "net/http" + "os" + "os/exec" + "strings" +) + +//go:embed web/* +var webFS embed.FS + +func main() { + addr := os.Getenv("LISTEN_ADDR") + if addr == "" { + addr = "127.0.0.1:8080" + } + + static, err := fs.Sub(webFS, "web") + if err != nil { + slog.Error("embed fs", "err", err) + os.Exit(1) + } + + indexHTML, err := fs.ReadFile(static, "index.html") + if err != nil { + slog.Error("read index", "err", err) + os.Exit(1) + } + + mux := http.NewServeMux() + mux.HandleFunc("GET /", func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/" { + http.NotFound(w, r) + return + } + uptime := uptimeLine() + body := strings.ReplaceAll(string(indexHTML), "{{uptime}}", html.EscapeString(uptime)) + w.Header().Set("Content-Type", "text/html; charset=utf-8") + w.Header().Set("Cache-Control", "no-store") + _, _ = w.Write([]byte(body)) + }) + mux.Handle("GET /style.css", http.FileServer(http.FS(static))) + + slog.Info("listening", "addr", addr) + if err := http.ListenAndServe(addr, mux); err != nil { + slog.Error("serve", "err", err) + os.Exit(1) + } +} + +func uptimeLine() string { + out, err := exec.Command("uptime").Output() + if err != nil { + return "uptime unavailable" + } + return strings.TrimSpace(string(out)) +} diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000..645b14c --- /dev/null +++ b/web/index.html @@ -0,0 +1,21 @@ + + + + + + cultist.club + + + +
+

Welcome home. Again.

+ +
+ {{uptime}} +
+
+ + \ No newline at end of file diff --git a/web/style.css b/web/style.css new file mode 100644 index 0000000..67f7301 --- /dev/null +++ b/web/style.css @@ -0,0 +1,58 @@ +:root { + --bg: #0a0a0a; + --fg: #e0e0e0; + --muted: #888; + --border: #333; +} + +*, +*::before, +*::after { + box-sizing: border-box; +} + +body { + margin: 0; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + background: var(--bg); + color: var(--fg); + font-family: monospace; +} + +.container { + text-align: center; + padding: 2rem; +} + +h1 { + font-size: 1.4rem; + font-weight: normal; + letter-spacing: 0.05em; +} + +.links { + margin-top: 1.5rem; + font-size: 0.85rem; +} + +.links a { + margin: 0 0.5rem; + color: var(--muted); +} + +.uptime { + margin-top: 2rem; + overflow: hidden; + max-width: 420px; + border: 1px solid var(--border); + padding: 0.3rem 0; +} + +.uptime marquee { + font-size: 0.85rem; + color: var(--muted); +} \ No newline at end of file