This commit is contained in:
jacekpoz 2024-09-13 20:08:41 +02:00
commit d883daa41c
Signed by: poz
SSH key fingerprint: SHA256:JyLeVWE4bF3tDnFeUpUaJsPsNlJyBldDGV/dIKSLyN8
16 changed files with 2492 additions and 0 deletions

7
.editorconfig Normal file
View file

@ -0,0 +1,7 @@
[*.html]
indent_style = space
indent_size = 2
[*.nix]
indent_style = space
indent_size = 2

1
.envrc Normal file
View file

@ -0,0 +1 @@
use flake

View file

@ -0,0 +1,17 @@
name: Deploy website
on:
push:
branches:
- master
paths:
- 'front/**'
- '.forgejo/workflows/deploy-front.yaml'
jobs:
deploy:
runs-on: native
steps:
- uses: actions/checkout@v3
- run: |
nix build -L .#site -o /srv/web/nixwebr.ing

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
result
.direnv

80
flake.lock Normal file
View file

@ -0,0 +1,80 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1717602782,
"narHash": "sha256-pL9jeus5QpX5R+9rsp3hhZ+uplVHscNJh8n8VpqscM0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e8057b67ebf307f01bdcc8fba94d94f75039d1f6",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nte": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"systems": "systems"
},
"locked": {
"lastModified": 1726242453,
"narHash": "sha256-VTHc10y2gI1CVmCayzzswPQPZ4S/QIi28VKpyfS+K1M=",
"ref": "refs/heads/main",
"rev": "b1f9ff4ed5fe38973c5c16db7b8c1f6100c52a5e",
"revCount": 51,
"type": "git",
"url": "https://git.jacekpoz.pl/jacekpoz/nte"
},
"original": {
"type": "git",
"url": "https://git.jacekpoz.pl/jacekpoz/nte"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs",
"nte": "nte",
"systems": "systems_2"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

46
flake.nix Normal file
View file

@ -0,0 +1,46 @@
{
description = "the ring";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nte = {
url = "git+https://git.jacekpoz.pl/jacekpoz/nte";
inputs.nixpkgs.follows = "nixpkgs";
};
systems.url = "github:nix-systems/default";
};
outputs = { nixpkgs, nte, self, systems, ... }: let
forEachSystem = nixpkgs.lib.genAttrs (import systems);
pkgsForEach = nixpkgs.legacyPackages;
in {
packages = forEachSystem (
system: let
pkgs = pkgsForEach.${system};
in {
site = import ./site/default.nix {
inherit pkgs;
inherit (pkgs) jetbrains-mono lib;
inherit (nte.functions.${system}) mkNteDerivation;
};
server = import ./server/default.nix {
inherit pkgs;
inherit (pkgs) rustPlatform;
};
}
);
devShells = forEachSystem (
system: let
pkgs = pkgsForEach.${system};
shell = pkgs.mkShell {
name = "nixwebr.ing";
inputsFrom = [ self.packages.${system}.server ];
};
in {
"nixwebr.ing" = shell;
default = shell;
}
);
};
}

1
server/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
target/

1932
server/Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

10
server/Cargo.toml Normal file
View file

@ -0,0 +1,10 @@
[package]
name = "nix-webring-server"
version = "0.1.0"
edition = "2021"
[dependencies]
env_logger = "0.11.3"
ntex = { version = "2.0.0", features = [ "tokio", "rustls" ] }
ntex-files = "2.0.0"
rand = "0.8.5"

9
server/default.nix Normal file
View file

@ -0,0 +1,9 @@
{rustPlatform, ...}:
rustPlatform.buildRustPackage {
pname = "nix-webring-server";
version = "0.1.0";
src = ./.;
cargoHash = "sha256-O+rhWIjIBQdemTsFc1TV/lpKZpGE/IL7uPs3TP8KVu0=";
}

83
server/src/main.rs Normal file
View file

@ -0,0 +1,83 @@
mod members;
use members::WEBRING_MEMBERS;
use ntex::{http::{header, Response}, web::{self, middleware}};
use ntex_files as nfs;
use ::rand::{thread_rng, Rng};
#[web::get("/next/{name}")]
async fn next(name: web::types::Path<String>) -> impl web::Responder {
if let Some((i, _)) = WEBRING_MEMBERS.iter().enumerate().find(|(_, member)| member.name == *name) {
let next_index = (i + 1) % WEBRING_MEMBERS.len();
let next_domain = WEBRING_MEMBERS[next_index].domain;
let next_url = format!("https://{next_domain}/");
return Response::PermanentRedirect()
.header(header::LOCATION, next_url)
.take();
}
Response::TemporaryRedirect()
.header(header::LOCATION, "https://nixwebr.ing/")
.take()
}
#[web::get("/prev/{name}")]
async fn prev(name: web::types::Path<String>) -> impl web::Responder {
if let Some((i, _)) = WEBRING_MEMBERS.iter().enumerate().find(|(_, member)| member.name == *name) {
let prev_index = if i == 0 { WEBRING_MEMBERS.len() - 1 } else { i - 1 };
let prev_domain = WEBRING_MEMBERS[prev_index].domain;
let prev_url = format!("https://{prev_domain}/");
return Response::PermanentRedirect()
.header(header::LOCATION, prev_url)
.take();
}
Response::TemporaryRedirect()
.header(header::LOCATION, "https://nixwebr.ing/")
.take()
}
#[web::get("/rand")]
async fn rand() -> impl web::Responder {
let rand_index = thread_rng().gen_range(0..WEBRING_MEMBERS.len());
let rand_domain = WEBRING_MEMBERS[rand_index].domain;
let rand_url = format!("https://{rand_domain}/");
Response::PermanentRedirect()
.header(header::LOCATION, rand_url)
.take()
}
#[ntex::main]
async fn main() -> std::io::Result<()> {
env_logger::init();
let nix_webring_dir = std::env::var("NIX_WEBRING_DIR")
.expect("NIX_WEBRING_DIR not found");
let nix_webring_port = std::env::var("NIX_WEBRING_PORT")
.expect("NIX_WEBRING_PORT not found")
.parse::<u16>()
.expect("NIX_WEBRING_PORT has to be u16");
web::server(move || {
web::App::new()
.wrap(middleware::Logger::default())
.service(
web::scope("/")
.service(next)
.service(prev)
.service(rand)
.service(
nfs::Files::new("/", nix_webring_dir.clone())
.index_file("index.html")
.redirect_to_slash_directory()
)
)
})
.bind(("127.0.0.1", nix_webring_port))?
.run()
.await
}

16
server/src/members.rs Normal file
View file

@ -0,0 +1,16 @@
// this is hilariously bad but I'm too lazy to do anything about it right now
pub struct WebringMember {
pub name: &'static str,
pub domain: &'static str,
}
pub const WEBRING_MEMBERS: &'static [WebringMember] = &[
WebringMember {
name: "poz",
domain: "jacekpoz.pl",
},
WebringMember {
name: "krizej",
domain: "krizej.codeberg.page",
},
];

39
site/default.nix Normal file
View file

@ -0,0 +1,39 @@
{
jetbrains-mono,
lib,
mkNteDerivation,
...
}: let
inherit (lib.attrsets) listToAttrs;
inherit (lib.lists) map;
inherit (lib.strings) replaceStrings toLower;
h = n: content: let
id = replaceStrings [" " ";"] ["-" "-"] (toLower content);
in /*html*/''
<h${toString n} id="${id}"><a href="#${id}">#</a> ${content}</h${toString n}>
'';
in mkNteDerivation {
name = "nix-webring-site";
version = "0.1.0";
src = ./.;
extraArgs = {
inherit h;
}
// listToAttrs (map (n: {
name = "h${toString n}";
value = text: h n text;
}) [ 1 2 3 4 5 6 ]
);
entries = [
./index.nix
];
extraFiles = [
{ source = "./index.css"; destination = "/"; }
{ source = "./nix-webring.svg"; destination = "/"; }
{ source = "${jetbrains-mono}/share/fonts/truetype/JetBrainsMono-Regular.ttf"; destination = "/"; }
];
}

21
site/index.css Normal file
View file

@ -0,0 +1,21 @@
@font-face {
font-family: "JetBrains Mono";
src: url(/JetBrainsMono-Regular.ttf) format("truetype");
}
* {
margin: 0;
padding: 0;
}
body {
background-color: #111111;
color: #DDDDDD;
font-family: "JetBrains Mono";
font-size: 1.15rem;
display: flex;
flex-direction: column;
align-items: center;
margin: 0;
height: 100%;
}

21
site/index.nix Normal file
View file

@ -0,0 +1,21 @@
_: {
template = "passthrough";
format = "html";
output = /*html*/''
<html lang="en">
<head>
<title>nix webring</title>
<link rel="icon" type="image/svg" href="/nix-webring.svg">
<link rel="stylesheet" href="/index.css">
<meta property="og:title" content="nix webring">
<meta property="og:image" content="https://jacekpoz.pl/nix-webring.svg">
<meta property="og:type" content="website">
<meta property="og:url" content="https://nixwebr.ing">
</head>
<body>
<p>work in progress</p>
</body>
</html>
'';
}

207
site/nix-webring.svg Normal file
View file

@ -0,0 +1,207 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="535"
height="535"
viewBox="0 0 501.56251 501.56249"
id="svg2"
version="1.1"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
sodipodi:docname="nix-webring.svg"
inkscape:export-filename="nix-webring.png"
inkscape:export-xdpi="107.66355"
inkscape:export-ydpi="107.66355"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
id="linearGradient5562">
<stop
style="stop-color:#699ad7;stop-opacity:1"
offset="0"
id="stop5564" />
<stop
id="stop5566"
offset="0.24345198"
style="stop-color:#7eb1dd;stop-opacity:1" />
<stop
style="stop-color:#7ebae4;stop-opacity:1"
offset="1"
id="stop5568" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient5053">
<stop
style="stop-color:#415e9a;stop-opacity:1"
offset="0"
id="stop5055" />
<stop
id="stop5057"
offset="0.23168644"
style="stop-color:#4a6baf;stop-opacity:1" />
<stop
style="stop-color:#5277c3;stop-opacity:1"
offset="1"
id="stop5059" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5053"
id="linearGradient4330"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(864.69589,-1491.3405)"
x1="-584.19934"
y1="782.33563"
x2="-496.29703"
y2="937.71399" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5562"
id="linearGradient1"
gradientUnits="userSpaceOnUse"
gradientTransform="rotate(60,1285.574,-127.0267)"
x1="200.59668"
y1="351.41116"
x2="290.08701"
y2="506.18814" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5562"
id="linearGradient2"
gradientUnits="userSpaceOnUse"
gradientTransform="rotate(-60,-541.80106,-249.3096)"
x1="200.59668"
y1="351.41116"
x2="290.08701"
y2="506.18814" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5562"
id="linearGradient3"
gradientUnits="userSpaceOnUse"
gradientTransform="rotate(180,372.09351,-188.18095)"
x1="200.59668"
y1="351.41116"
x2="290.08701"
y2="506.18814" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5053"
id="linearGradient4"
gradientUnits="userSpaceOnUse"
gradientTransform="rotate(120,405.50413,279.20289)"
x1="-584.19934"
y1="782.33563"
x2="-496.29703"
y2="937.71399" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5053"
id="linearGradient5"
gradientUnits="userSpaceOnUse"
gradientTransform="rotate(-120,-455.57263,-219.8159)"
x1="-584.19934"
y1="782.33563"
x2="-496.29703"
y2="937.71399" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.70710678"
inkscape:cx="428.50671"
inkscape:cy="330.92597"
inkscape:document-units="px"
inkscape:current-layer="g2"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1404"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:snap-global="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:showpageshadow="2"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:groupmode="layer"
id="layer3"
inkscape:label="gradient-logo"
style="display:inline;opacity:1"
transform="translate(-156.41121,933.30685)">
<g
id="g2"
transform="matrix(0.99994059,0,0,0.99994059,-0.06321798,33.188377)"
style="stroke-width:1.00006">
<g
id="g5"
transform="matrix(1.5923554,0,0,1.5923554,-241.25483,424.14882)">
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="use3439-6"
d="m 353.65459,-797.57947 -75.33983,131.03333 -28.53475,-48.37004 14.05181,-24.82625 33.4638,-57.69041 z"
style="fill:url(#linearGradient1);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.00018;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="use3445-0"
d="m 363.03058,-628.3791 150.65887,0.012 -27.6223,48.89684 -28.03684,-0.0386 -66.69326,-0.1353 z"
style="fill:url(#linearGradient2);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.00018;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="use3449-5"
d="m 505.28844,-721.12473 -75.88193,-131.23275 56.15706,-0.5268 14.54791,25.05223 33.22946,57.8257 z"
style="fill:url(#linearGradient3);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.00018;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient4330);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.00018;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 309.54892,-710.38827 75.60056,130.67022 -56.15706,0.5268 -14.26654,-24.4897 -33.22946,-57.8256 z"
id="path4260-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccc" />
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient4);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.00018;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 451.30201,-803.62004 -150.65887,-0.012 27.62231,-48.89684 28.03683,0.0386 66.69317,0.13525 z"
id="use4354-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccc" />
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient5);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.00018;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 460.90516,-633.96606 75.33983,-131.03333 28.53475,48.37004 -14.05181,24.82625 -33.46371,57.69035 z"
id="use4362-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccc" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.7 KiB