Compare commits

...

26 Commits
main ... main

Author SHA1 Message Date
Charlotte Som 80ba6a1f02 Update miles page 2022-08-28 07:33:53 +01:00
Charlotte Som 2e6ca1a884 class -> href 2022-08-28 07:30:24 +01:00
Charlotte Som a231108b9c Add miles to webring, remove members section of homepage, add Hermes 2022-08-18 02:00:45 +01:00
Charlotte Som 74885b0410 Add members to site 2022-03-17 11:45:59 +00:00
Luna afccae891d
add easrng's job title 2022-03-14 15:36:13 -04:00
maia arson crimew 027451fa6d update maia info 2022-03-14 16:04:24 +00:00
Luna 59e9973a25 Update Luna's member description 2022-03-14 16:04:24 +00:00
Charlotte Som 1e27c8ec39 [WIP] Update member list 2022-03-14 16:04:24 +00:00
Charlotte Som 4e7a5aefa7 Add easrng to webring 2022-03-14 09:05:16 +00:00
maia arson crimew b6f992b46a add maia to the webring 2022-03-09 13:28:09 +01:00
Charlotte Som a777aea815 Revert "The CORS header should cover the entire webring directory"
Wait no it shouldn't we're fine
2022-03-05 20:28:54 +00:00
Charlotte Som e2f4635404 The CORS header should cover the entire webring directory 2022-03-05 20:27:16 +00:00
Charlotte Som 1e1fe5b82f Auto-calculate subresource integrity for webring JS 2022-03-05 20:23:41 +00:00
Charlotte Som c32320fec4 Create version 2 of the webring 2022-03-05 20:20:02 +00:00
Charlotte Som e9f60bf7e7 jill 2022-03-05 19:07:17 +00:00
Charlotte Som 9bf90c9715 Reformat data.json 2022-03-05 19:06:34 +00:00
Charlotte Som 3e561b8474 Rewrite the nginx site config 2022-03-05 17:45:24 +00:00
Charlotte Som 4f40930dd5 Update projects list 2022-03-05 15:47:33 +00:00
Charlotte Som 26b30cd030 Simplify watch loop 2022-03-05 15:25:54 +00:00
Charlotte Som 89f26b9a0e Fix typo: 'th eone' -> 'the one' 2022-03-05 15:04:58 +00:00
Charlotte Som 1e1dfbc18a Merge pull request 'lavender.software webring' (#2) from patch/webring into main
Reviewed-on: lavender/lavender.software#2
2022-03-05 15:00:47 +00:00
Charlotte Som 0da2c0459d Mention the nginx-site.conf file in the README's Deploying section 2022-03-05 15:00:01 +00:00
Charlotte Som 4b2d9f5d11 Add sample nginx site configuration
Since we have to set the CORS header for data.json, we make sure that
there's some form of documentation in this repo
2022-03-05 14:58:49 +00:00
Charlotte Som 5e29b82c8d Resolve webring merge conflicts after changes to main 2022-03-05 14:50:56 +00:00
Charlotte Som ab9e7598be Convert line endings to LF 2022-03-05 14:41:57 +00:00
Charlotte Som 1e235dd0d1 Add setup instructions to the README 2022-03-05 14:38:32 +00:00
21 changed files with 746 additions and 569 deletions

View File

@ -3,7 +3,7 @@ root = true
[*]
indent_style = space
indent_size = 2
end_of_line = crlf
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = false
insert_final_newline = true

63
Cargo.lock generated
View File

@ -89,6 +89,15 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "base64"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
dependencies = [
"byteorder",
]
[[package]]
name = "bitflags"
version = "1.2.1"
@ -416,6 +425,12 @@ dependencies = [
"libc",
]
[[package]]
name = "hex"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
[[package]]
name = "html5ever"
version = "0.25.1"
@ -492,6 +507,7 @@ dependencies = [
"askama",
"notify",
"siru",
"ssri",
]
[[package]]
@ -973,6 +989,18 @@ dependencies = [
"opaque-debug",
]
[[package]]
name = "sha2"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69"
dependencies = [
"block-buffer",
"digest",
"fake-simd",
"opaque-debug",
]
[[package]]
name = "shell-words"
version = "1.0.0"
@ -1006,6 +1034,21 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527"
[[package]]
name = "ssri"
version = "7.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9cec0d388f39fbe79d7aa600e8d38053bf97b1bc8d350da7c0ba800d0f423f2"
dependencies = [
"base64",
"digest",
"hex",
"serde",
"sha-1",
"sha2",
"thiserror",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
@ -1080,6 +1123,26 @@ dependencies = [
"unicode-width",
]
[[package]]
name = "thiserror"
version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "time"
version = "0.1.44"

View File

@ -14,3 +14,4 @@ path = "build_src/main.rs"
askama = "0.10.5"
notify = "4.0.17"
siru = { git = "https://github.com/videogame-hacker/siru.git" }
ssri = "7.0.0"

View File

@ -2,8 +2,23 @@
Static site generated using [siru](https://github.com/videogame-hacker/siru) and hosted at [lavender.software](https://lavender.software/).
## Setting Up
```shell
$ git clone 'git@lavender.software:lavender/lavender.software.git'
$ cd lavender.software/
lavender.software/ $ mkdir dist # or follow instructions in 'Deploying'
lavender.software/ $ cargo run
...
lavender.software/ $ # Built files are in dist/
```
You may want to `cd dist && python -m http.server` to get a local HTTP server.
## Deploying
**Note:** You don't need to do this unless you're the one deploying the site to the production environment.
```shell
$ # To set up, ensure that the 'dist' folder reflects the VPS
$ git clone 'root@lavender.software:/srv/http/lavender.software' dist
@ -15,3 +30,5 @@ dist/ $ git pull --rebase
dist/ $ git push
dist/ $ # Your changes should now be live at lavender.software
```
If deploying this site, you may also want to examine the sample `nginx-site.conf` file.

View File

@ -74,11 +74,8 @@ fn main() {
let mut watcher = watcher(tx, Duration::from_millis(100)).unwrap();
watcher.watch("./src", RecursiveMode::Recursive).unwrap();
loop {
match rx.recv() {
Ok(_) => build(),
Err(_) => break,
}
while rx.recv().is_ok() {
build()
}
}
}

View File

@ -1,58 +1,13 @@
use crate::*;
struct Member {
name: String,
website: String,
title: String,
}
impl From<&(&str, &str, &str)> for Member {
fn from(tuple: &(&str, &str, &str)) -> Self {
Member {
name: tuple.0.to_string(),
website: tuple.1.to_string(),
title: tuple.2.to_string(),
}
}
}
#[derive(Template)]
#[template(path = "main_page.html.j2")]
struct MainPageTemplate {
members: Vec<Member>,
}
struct MainPageTemplate {}
pub fn main_page(ctx: &BuildContext) -> Result<()> {
log_info("Rendering main page…");
let members = [
("charlotte som", "https://som.codes/", "founder"),
("agatha rose", "https://agatharose.dev/", "meow"),
("maya", "https://1312.gay/", "chief director of maya"),
(
"Luna Lulu",
"https://lunaisa.dev",
"critically acclaimed website maker",
),
(
"annie versario",
"https://annie.kitty.lgbt",
"regional marquee technician",
),
(
"The System",
"https://the-system.eu.org",
"lead systems specialist",
),
];
ctx.write(
"index.html",
MainPageTemplate {
members: members.iter().map(|x| x.into()).collect(),
}
.render()?,
)?;
ctx.write("index.html", MainPageTemplate {}.render()?)?;
Ok(())
}

View File

@ -1,5 +1,7 @@
use crate::*;
use ssri::{Algorithm, IntegrityOpts};
pub fn copy_webring(ctx: &BuildContext) -> Result<()> {
log_info("Copying webring…");
copy_dir_recursive(
@ -7,5 +9,15 @@ pub fn copy_webring(ctx: &BuildContext) -> Result<()> {
ctx.output_dir.join("webring"),
)?;
log_info("Calculating webring integrity…");
let webring_content = ctx.read_bin("webring/webring-0.2.0.js")?;
let integrity = IntegrityOpts::new()
.algorithm(Algorithm::Sha512)
.algorithm(Algorithm::Sha1)
.chain(&webring_content)
.result();
ctx.write("webring/webring-0.2.0.js.integ.txt", integrity.to_string())?;
Ok(())
}

11
nginx-site.conf Normal file
View File

@ -0,0 +1,11 @@
# assuming the dist repo lives at /srv/http/lavender.software
location / {
root /srv/http/lavender.software/;
location = /webring/data.json {
add_header Access-Control-Allow-Origin *;
}
}
error_page 404 /404.html

View File

@ -1,17 +1,37 @@
[
{
"id": "annie",
"name": "annieversary",
"url": "https://versary.town/"
},
{
"id": "charlotte",
"name": "charlotte",
"url": "https://char.lt/"
},
{
"id": "mira",
"name": "mira",
"url": "https://boxin.space/"
}
{
"id": "annie",
"name": "annieversary",
"url": "https://versary.town/"
},
{
"id": "charlotte",
"name": "charlotte",
"url": "https://char.lt/"
},
{
"id": "milse113",
"name": "milse113",
"url": "https://milse113.github.io/lavender.html"
},
{
"id": "mira",
"name": "mira",
"url": "https://boxin.space/"
},
{
"id": "oatmealine",
"name": "oatmealine",
"url": "https://oat.zone/"
},
{
"id": "maia",
"name": "maia",
"url": "https://maia.crimew.gay/"
},
{
"id": "easrng",
"name": "easrng",
"url": "https://easrng.net/"
}
]

View File

@ -0,0 +1,162 @@
(function () {
function getUID() {
var array = new Uint8Array(8);
window.crypto.getRandomValues(array);
return Array.from(array)
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
}
const params = document.currentScript.dataset;
const UID = getUID();
const css = `
#--lavender-cssreset-${UID} {
all: unset;
}
#--lavender-webring-container-${UID} {
background-color: rgb(28, 23, 36);
background-blend-mode: multiply;
position: relative;
background-color: ${params.backgroundColor || "purple"};
color: ${params.textColor || "white"};
text-shadow: 0px 1px 1px ${params.textShadowColor || "black"};
padding: 1px;
font-size: 16px;
font-family: sans-serif;
margin: 10px 0px;
}
#--lavender-webring-container-${UID} a {
color: inherit !important;
}
#--lavender-webring-container-${UID}::before {
display: block;
content: ' ';
top: 0; left: 0; bottom: 0; right: 0;
position: absolute;
box-sizing: border-box;
pointer-events: none;
border: 5px outset;
opacity: 0.25;
border-color: white black black white;
}
#--lavender-webring-container-${UID} #--lavender-webring-title-${UID} {
margin: 10px 10px 0px;
text-align: center;
font-style: italic;
}
#--lavender-webring-container-${UID} #--lavender-webring-item-container-${UID} {
display: flex;
justify-content: space-around;
}
@media (max-width: 600px) {
#--lavender-webring-container-${UID} #--lavender-webring-item-container-${UID} {
flex-direction: column;
}
}
#--lavender-webring-container-${UID} .--lavender-webring-items-${UID} {
font-size: 14px;
display: block;
text-align: center;
padding: 0px;
margin: 10px 10px 8px;
flex: 1;
}
#--lavender-webring-container-${UID} #--lavender-webring-item-1-${UID}::before {
display: inline;
content: '\\2190\\00a0';
}
#--lavender-webring-container-${UID} #--lavender-webring-item-3-${UID}::after {
display: inline;
content: '\\00a0\\2192';
}
`;
const webring_content = `
<div id="--lavender-cssreset-${UID}">
<div id="--lavender-webring-container-${UID}">
<p id="--lavender-webring-title-${UID}">This website is a part of the Lavender Software webring</p>
<div id="--lavender-webring-item-container-${UID}">
<a class="--lavender-webring-items-${UID}" id="--lavender-webring-item-1-${UID}"></a>
<a class="--lavender-webring-items-${UID}" id="--lavender-webring-item-2-${UID}"></a>
<a class="--lavender-webring-items-${UID}" id="--lavender-webring-item-3-${UID}"></a>
</div>
</div>
</div>
`;
function renderIdx(data, element, idx) {
idx = (idx + data.length) % data.length;
datum = data[idx];
element.textContent = datum.name;
element.href = datum.url;
}
function getElementByPostfixedId(path) {
return document.getElementById(path + "-" + UID);
}
function renderContent(currentScript, data) {
const params = currentScript.dataset;
var headstyle = document.createElement("style");
headstyle.innerHTML = css;
document.head.appendChild(headstyle);
currentScript.insertAdjacentHTML("afterend", webring_content);
const container = getElementByPostfixedId("--lavender-webring-container");
const item1 = getElementByPostfixedId("--lavender-webring-item-1");
const item2 = getElementByPostfixedId("--lavender-webring-item-2");
const item3 = getElementByPostfixedId("--lavender-webring-item-3");
const id = params.siteId;
var idindex = -1;
for (var i = 0; i < data.length; i++) {
if (data[i].id == id) {
idindex = i;
}
}
if (idindex == -1) {
item2.textContent =
"this site was not found in the list. please check that you don't have any typos in the id!";
return;
}
if ("hideTitle" in params) {
getElementByPostfixedId("--lavender-webring-title").style.display =
"none";
}
renderIdx(data, item1, idindex - 1);
renderIdx(data, item2, idindex);
renderIdx(data, item3, idindex + 1);
}
const currentScript = document.currentScript;
if (currentScript) {
fetch("https://lavender.software/webring/data.json")
.then(function (response) {
return response.json();
})
.then(function (data) {
renderContent(currentScript, data);
});
} else {
console.log("cannot locate document.currentScript element. aborting...");
}
})();

View File

@ -0,0 +1,52 @@
/* Feel free to style the webring however you like! */
.lavender-webring-container {
all: unset;
/*
assuming Linux users will have a preferable sans-serif font set in their browser,
everyone else gets a nice default
*/
font-family: -apple-system, BlinkMacSystemFont, "SF Pro", "Segoe UI",
"Helvetica Neue", sans-serif;
display: flex;
flex-direction: column;
background-color: rgb(28, 23, 36);
color: rgb(234, 234, 248);
padding: 1em;
text-align: center;
font-size: 1.125rem;
}
.lavender-webring-description {
margin-block-end: 0.5em;
}
.lavender-webring-container a {
color: hsl(275, 57%, 68%);
text-decoration: none;
border-bottom: 1px solid hsl(275, 57%, 68%);
}
.lavender-webring-site-links {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
list-style: none;
margin: 0;
padding: 0;
}
.lavender-webring-prev-site a::before {
content: "←";
margin-inline-end: 1ch;
}
.lavender-webring-next-site a::after {
content: "→";
margin-inline-start: 1ch;
}

View File

@ -0,0 +1,54 @@
const currentScript = document.currentScript;
const ctx = currentScript.dataset;
// charlotte's ad-hoc terse javascript framework!
const CSS_PREFIX = "lavender-webring";
const e = (tag, props = {}, children = []) => {
let element = Object.assign(document.createElement(tag), props);
element.append(...children);
return element;
};
const t = (text) => document.createTextNode(text);
const c = (className) => ({ className: `${CSS_PREFIX}-${className}` });
const h = (href) => ({ href });
const createDescriptionContent = () =>
ctx.description != null
? [t(ctx.description)]
: [
t("This site is part of the "),
e("a", h("https://lavender.software"), [t("lavender.software")]),
t(" webring!"),
];
const renderWebring = (currSite, prevSite, nextSite) => {
currentScript.replaceWith(
e("aside", c("container"), [
e("section", c("description"), createDescriptionContent()),
e("ul", c("site-links"), [
e("li", c("prev-site"), [e("a", h(prevSite.url), [t(prevSite.name)])]),
e("li", c("curr-site"), [e("a", h(currSite.url), [t(currSite.name)])]),
e("li", c("next-site"), [e("a", h(nextSite.url), [t(nextSite.name)])]),
]),
])
);
};
(async () => {
const data = await fetch("https://lavender.software/webring/data.json").then(
(r) => r.json()
);
let thisSiteIdx = data.findIndex((site) => site.id == ctx.siteId);
if (thisSiteIdx === -1) {
throw new Error(
`Could not find site by id '${ctx.siteId}' in the webring!`
);
}
let currSite = data[thisSiteIdx];
let prevSite = data[(thisSiteIdx + data.length - 1) % data.length];
let nextSite = data[(thisSiteIdx + 1) % data.length];
renderWebring(currSite, prevSite, nextSite);
})();

View File

@ -1,157 +0,0 @@
(function() {
function getUID() {
var array = new Uint8Array(8);
window.crypto.getRandomValues(array);
return Array.from(array).map(b => b.toString(16).padStart(2, "0")).join("");
}
const params = document.currentScript.dataset;
const UID = getUID();
const css = `
#--lavender-cssreset-${UID} {
all: unset;
}
#--lavender-webring-container-${UID} {
background-color: rgb(28, 23, 36);
background-blend-mode: multiply;
position: relative;
background-color: ${params.backgroundColor || "purple"};
color: ${params.textColor || "white"};
text-shadow: 0px 1px 1px ${params.textShadowColor || "black"};
padding: 1px;
font-size: 16px;
font-family: sans-serif;
margin: 10px 0px;
}
#--lavender-webring-container-${UID} a {
color: inherit !important;
}
#--lavender-webring-container-${UID}::before {
display: block;
content: ' ';
top: 0; left: 0; bottom: 0; right: 0;
position: absolute;
box-sizing: border-box;
pointer-events: none;
border: 5px outset;
opacity: 0.25;
border-color: white black black white;
}
#--lavender-webring-container-${UID} #--lavender-webring-title-${UID} {
margin: 10px 10px 0px;
text-align: center;
font-style: italic;
}
#--lavender-webring-container-${UID} #--lavender-webring-item-container-${UID} {
display: flex;
justify-content: space-around;
}
@media (max-width: 600px) {
#--lavender-webring-container-${UID} #--lavender-webring-item-container-${UID} {
flex-direction: column;
}
}
#--lavender-webring-container-${UID} .--lavender-webring-items-${UID} {
font-size: 14px;
display: block;
text-align: center;
padding: 0px;
margin: 10px 10px 8px;
flex: 1;
}
#--lavender-webring-container-${UID} #--lavender-webring-item-1-${UID}::before {
display: inline;
content: '\\2190\\00a0';
}
#--lavender-webring-container-${UID} #--lavender-webring-item-3-${UID}::after {
display: inline;
content: '\\00a0\\2192';
}
`;
const webring_content = `
<div id="--lavender-cssreset-${UID}">
<div id="--lavender-webring-container-${UID}">
<p id="--lavender-webring-title-${UID}">This website is a part of the Lavender Software webring</p>
<div id="--lavender-webring-item-container-${UID}">
<a class="--lavender-webring-items-${UID}" id="--lavender-webring-item-1-${UID}"></a>
<a class="--lavender-webring-items-${UID}" id="--lavender-webring-item-2-${UID}"></a>
<a class="--lavender-webring-items-${UID}" id="--lavender-webring-item-3-${UID}"></a>
</div>
</div>
</div>
`;
function renderIdx(data, element, idx) {
idx = (idx + data.length) % data.length;
datum = data[idx];
element.textContent = datum.name;
element.href = datum.url;
}
function getElementByPostfixedId(path) {
return document.getElementById(path + "-" + UID);
}
function renderContent(currentScript, data) {
const params = currentScript.dataset;
var headstyle = document.createElement('style');
headstyle.innerHTML = css;
document.head.appendChild(headstyle);
currentScript.insertAdjacentHTML("afterend", webring_content);
const container = getElementByPostfixedId('--lavender-webring-container');
const item1 = getElementByPostfixedId('--lavender-webring-item-1');
const item2 = getElementByPostfixedId('--lavender-webring-item-2');
const item3 = getElementByPostfixedId('--lavender-webring-item-3');
const id = params.siteId;
var idindex = -1;
for (var i = 0; i < data.length; i++) {
if (data[i].id == id) {
idindex = i;
}
}
if (idindex == -1) {
item2.textContent = "this site was not found in the list. please check that you don't have any typos in the id!";
return;
}
if ("hideTitle" in params) {
getElementByPostfixedId('--lavender-webring-title').style.display = 'none';
}
renderIdx(data, item1, idindex - 1);
renderIdx(data, item2, idindex);
renderIdx(data, item3, idindex + 1);
}
const currentScript = document.currentScript;
if (currentScript) {
fetch("https://lavender.software/webring/data.json").then(function(response) {
return response.json();
}).then(function(data) {
renderContent(currentScript, data);
});
} else {
console.log("cannot locate document.currentScript element. aborting...");
}
})();

View File

@ -25,23 +25,13 @@
<ul>
<li><a href="https://git.lain.faith/videogame-hacker/discord-css-injector">lavender cord</a> - a theming platform for Discord</li>
<li>more soon!</li>
<li><a href="https://git.lavender.software/lavender/watch-party">watch-party</a> - a webapp to allow for synced video playback among friends</li>
<li>catsette <em>(upcoming)</em> - an independent music marketplace platform for artists</li>
<li>Hermes <em>(upcoming)</em> - a native <a href="https://scuttlebutt.nz/">Secure Scuttlebutt</a> client for Linux</li>
<li>&hellip; and more soon!</li>
</ul>
</section>
<!--
<section>
<h2>who are we?</h2>
<ul>
{% for member in members %}
<li>
<a href="{{ member.website }}">{{ member.name }}</a> - {{ member.title }}
</li>
{% endfor %}
</ul>
</section> -->
<section>
<h2>services</h2>