This commit is contained in:
sophie 2024-02-14 03:59:56 +00:00
parent 6266095111
commit 0755c1ccec
7 changed files with 240 additions and 84 deletions

View File

@ -1,58 +1,13 @@
# zvava.org
static website generator (html and gemini) for my personal website [zvava.org](zvava.org)
static website generator (html and gemini) for my personal website [zvava.org](https://zvava.org)
## [to do] rewrite no. 4
re write the whole website again but in [wren](https://wren.io) and yeah
## contributing
the `qjs wiki.js` utility is provided to help me (and you!) to create modifications to the wiki
the `qjs wiki.js` utility is provided to help me (and you!) to create modifications to the wiki. it has usage information built in, the most useful of which are `new` and `make`. to make development faster you may `alias wiki="qjs wiki.js"`
usage: `qjs wiki.js command args`
commands:
* `list`: list all wiki pages
* `new`: create a new wiki page
* `edit`: edit a wiki page
* `rm`: delete wiki pages
each command has it's own arguments, to list use `qjs wiki.js command -h`
### `list`
prints out a list of every single page, takes a combination of characters as an argument
`usage: qjs wiki.js list [-hlLcTIEAMVHS]`
* `-`: noop
* `h`: display usage information
* `t`: show TODOs
* `a`: show local links
* `d`: show dead local links
* `l`: list categories of pages as well
* `p`: add padding to the list :)
* `c`: sort by created date instead of modified date
> using both `a` and `d` is identical to using just `d`
you can filter by categories using the captial first letter of a category;
`s`tub (no category), `T`ext, `I`nfo, `E`vent, `A`rt, `M`usic, `V`ideo, `H`ardware, `S`oftware
### `edit`
makes changes to a page
`usage: qjs wiki.js edit [arg] page`
argument:
* `(no argument)`: open the page in nano
* `-h --help`: display usage information
* `-m --modify`: set modified date to today's date
### `rm`
delete a page or pages. if you need to be safe you can type out pages to remove first, then go up in history to confirm the deletion by adding `-y` to the end of the command
`usage: qjs wiki.js rm [-h] [pages]`
* `-h --help`: display usage information
* `-y --yes`: confirm deletion
### `new`
### new page
create a new wiki page with placeholder content
`usage: qjs wiki.js new page [args...]`
@ -79,15 +34,15 @@ add content:
* `-a --alt`: set alt text of previous image/link
## development
run `qjs make.js` to create out/, out/gemini/, and out/www/, then generate contents
run `qjs make.js` (or `wiki make` if you have the alias) to create out/, out/gemini/, and out/www/, then generate contents
run `webserver 80 out/www/` (`npm i -g webserver`) to debug html output
run `webserver 8080 out/www/` (`npm i -g webserver`) to debug html output
https://github.com/mbrubeck/agate
run `agate --content out/gemini/ --host localhost` to debug gemini output ([agate](https://github.com/mbrubeck/agate))
## production
make sure all changes are committed and pushed
run `publish.bat` on windows or `publish.sh` on unix and enter password to sync changes with the webserver
run `qjs wiki.js publish` and enter password to sync changes with the webserver
remote server will fetch the latest version of this repo, and run the publish.sh script. this builds the site remotely and copies `out/gemini/` to `/var/gemini/content/` and `out/www/` to `/var/www/`
remote server will fetch the latest version of this repo, and run the publish.sh script. this builds the site remotely and copies `out/gemini/` to `/var/gemini/content/` and `out/www/` to `/var/www/`sass

75
caddy/Caddyfile Normal file
View File

@ -0,0 +1,75 @@
zvava.org {
# discrimination
@operagx header_regexp Sec-Ch-Ua "(?i)(opera gx)"
respond @operagx "gamers not allowed" 400
@brave header_regexp Cookie "(?i)(Brave-User)"
respond @brave "you are not brave enough" 400
# media
@media path /media /media/*
route @media {
uri strip_prefix /media
file_server {
root /var/lib/syncthing/zvava.org.media/
hide .*
browse /etc/caddy/browse.tmpl
pass_thru
}
}
# wiki
root * /var/www
file_server
# firefox fix
rewrite /favicon.ico /images/favicon.ico
# inline files fix
@inline path *.ass *.bat *.txt
header @inline {
Content-Type text/plain
Content-Disposition inline
}
# api
@api path /api /api/
@viewcount path /api/viewcount /api/viewcount/*
@ntfy path /api/ntfy /api/ntfy/*
reverse_proxy @viewcount localhost:8001
reverse_proxy @ntfy localhost:8002
respond @api `["viewcount", "ntfy"]`
handle_errors {
handle /api/* {
header Content-Type application/json
respond `{"code": {err.status_code}, "message": "{err.message}"}`
}
@404 expression {err.status_code} == 404
handle @404 {
header Content-Type "text/html; charset=utf-8"
header -Content-Disposition
rewrite * /wiki/404.html
file_server
}
handle {
respond "{err.status_code} {err.status_text}"
}
}
}
magenta.zvava.org {
root * /var/magenta.www
file_server
handle_errors {
@404 expression {err.status_code} == 404
rewrite @404 /404.html
file_server
}
}
git.zvava.org {
reverse_proxy * localhost:8080
}

109
caddy/browse.tmpl Normal file
View File

@ -0,0 +1,109 @@
{{- define "icon"}}
{{- if .IsDir}}
📁
{{- else if .HasExt ".jpg" ".jpeg" ".png" ".gif" ".webp" ".tiff" ".bmp" ".heif" ".heic" ".svg" ".ico"}}
🖼️
{{- else if .HasExt ".mp4" ".mov" ".m4v" ".mpeg" ".mpg" ".avi" ".ogg" ".webm" ".mkv" ".vob" ".gifv" ".3gp"}}
🎞️
{{- else if .HasExt ".mp3" ".m4a" ".aac" ".ogg" ".flac" ".wav" ".wma" ".midi" ".cda"}}
💿
{{- else if .HasExt ".csv" ".tsv" ".json" ".json5" ".jsonc" ".ini" ".inc" ".toml" ".conf" ".csproj"}}
🗒️
{{- else if .HasExt ".html" ".htm" ".pdf" ".doc" ".docx" ".odt" ".fodt" ".rtf" ".xls" ".xlsx" ".ods" ".fods" ".ppt" ".pptx" ".odp" ".fodp"}}
📑
{{- else if .HasExt ".zip" ".gz" ".xz" ".tar" ".7z" ".rar" ".xz" ".zst"}}
📦
{{- else if .HasExt ".ps1" ".bash" ".sh" ".wren" ".bat" ".exe"}}
💾
{{- else if .HasExt ".iso" ".img" ".dsk" ".deb" ".dpkg" ".rpm" ".exe" ".rmskin" ".appimage" ".msi" ".apk" ".dmg"}}
💽
{{- else if .HasExt ".md" ".mdown" ".markdown" ".gmi"}}
📝
{{- else if .HasExt ".ttf" ".otf" ".woff" ".woff2" ".eof"}}
🔣
{{- else if .HasExt ".com" ".dll" ".php" ".so" ".go" ".js" ".css" ".ts" ".py" ".pyc" ".pyo" ".cs" ".c" ".jar"}}
🧩
{{- else if .HasExt ".sql" ".db" ".sqlite" ".bak" ".mdb"}}
🗄️
{{- else if .HasExt ".eml" ".email" ".mailbox" ".mbox" ".msg"}}
✉️
{{- else if .HasExt ".crt" ".pem" ".x509" ".cer" ".ca-bundle"}}
🧾
{{- else if .HasExt ".key" ".keystore" ".jks" ".p12" ".pfx" ".pub"}}
🔑
{{- else}}
📄
{{- end}}
{{- end}}
<!DOCTYPE html>
<html>
<head>
<title>{{html .Name}}</title>
<link rel="canonical" href="{{.Path}}/" />
<meta charset="utf-8">
<meta name="color-scheme" content="light dark">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
max-width: 80ch;
margin: 1rem 2rem;
font-family: monospace;
font-size: 1.1rem; }
hr { border: none; height: 1px;
background: #444;
margin: 1rem 0; }
.entry {
display: flex; }
.entry .date {
width: 10ch; }
.entry .a {
padding: 0 1ch;
flex: 1;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap; }
a[href]:hover, a[href]:focus {
color: #b58bf9; }
@media (prefers-color-scheme: dark) {
body {
background: #1c1c1c;
color: #bbb; }
a {
color: #eee; }
}
</style>
</head>
<body>
<div class="entries">
<div class="entry">
<span class="date"></span>
<span class="a">📂 /{{range $i, $crumb := .Breadcrumbs}}<a href="{{html $crumb.Link}}">{{if eq $i 0}}media{{else}}{{html $crumb.Text}}{{end}}</a>/{{end}}</span>
<span class="size">
<b>{{.NumDirs}}</b> dir{{if ne 1 .NumDirs}}s{{end}}
<b>{{.NumFiles}}</b> file{{if ne 1 .NumFiles}}s{{end}}
</span>
</div>
<hr>
{{- range .Items}}
<div class="entry">
<span class="date">{{html (.HumanModTime "2006/01/02")}}</span>
<span class="a">{{template "icon" .}} <a href="{{html .URL}}">{{html .Name}}</a></span>
<span class="size">{{if .IsDir}}—{{else}}{{.HumanSize}}{{end}}</span>
</div>
{{- end}}
<hr>
<div class="entry">
<span class="date"></span>
</div>
</div>
</body>
</html>

28
make.js
View File

@ -188,13 +188,13 @@ function generateGemini() {
function generateHTML(files) {
print("\x1b[90m->\x1b[0m generating html site...")
files["stats"] = files["stats"] // add graph to stats page
.replace("=> https://zvava.org/stats.html requires javascript to work :l", "{stats}")
files["wiki/about-site"] = files["wiki/about-site"] // alternate gemini links to https on about page
.replace("=> https://zvava.org 🕸️ view html version", "=> gemini://zvava.org 🚀 view gemini version")
let count = 0
// iterate over each page and render final html
@ -243,11 +243,13 @@ function generateHTML(files) {
.replace(/^[-*+] +(.*)/, "<span class=\"ui\">$1</span>")
.replace(/^([0-9a-bA-B\.]+)\. +(.*)/, "<span class=\"oi\" data-i=\"$1\">$2</span>")
if (f == "wiki/index" && l.startsWith("<a href=\"/wiki/")) {
let start = l.indexOf("/wiki/") + 6 // get start of link
let end = l.indexOf(".html", start) // get end of link
if (f == "index" && /href="https:\/\/(mk\.catgirlsfor\.science|git\.zvava\.org|www\.buymeacoffee\.com|matrix\.to)/.test(l))
l = l.replace(">", "rel=\"me\">") // add rel=me attribute to some links
if (f == "wiki/index" && l.startsWith("<a href=\"/wiki/")) { // to append data-category attribute for filters
let start = l.indexOf("/wiki/") + 6, end = l.indexOf(".html", start)
let page = pages.find(x => x.page == l.substring(start, end)) // get linked page
l = l.replace(">", ` data-category="${page.category.join(" ")}">`) // add category attribute
l = l.replace(">", ` data-category="${page.category.join(" ")}">`) // add
}
// will this line be considered for its spacing?
@ -283,7 +285,7 @@ function generateHTML(files) {
output = output.replace("<p>{stats}</p>\n", templates["stats.html"]) // replace statustics tempalte
+ templates["viewcounter.html"].replace("{url}", "/" + f + ".html")
} else if (f == "wiki/index") { // wiki home page
// use filter template
// use filter template
output = output.replace("<p>{html_filter}<br>\n", templates["filter.html"] + "<p>")
// pass down data-category attribute from <a> to <p>s and <pre>s
.replace(/<p><a (href=".+?") (data-category=".+?")>(.+?)<\/a><\/p>\n<pre>/gm, "<p $2><a $1>$3</a></p>\n<pre $2>")
@ -331,11 +333,11 @@ function prependRelevantEmoji(x) {
let e = ""
switch (x) {
case "text": e += "📝"; break
case "info": e += "🧠"; break
case "event": e += "🍾"; break
case "art": e += "🎨"; break
case "music": e += "🎵"; break
case "video": e += "📺"; break
case "info": e += "📑"; break
case "event": e += "📅"; break
case "art": e += "🖼️"; break
case "music": e += "🎶"; break
case "video": e += "🎞️"; break
case "hardware": e += "🔧"; break
case "software": e += "💾"; break
}

View File

@ -15,15 +15,15 @@
<div class="label">
<label class="all-label" for="all" >*️⃣ all</label>
<label class="text-label" for="text" >📝 text</label>
<label class="info-label" for="info" >🧠 info</label>
<label class="info-label" for="info" >📑 info</label>
<label class="hardware-label" for="hardware">🔧 hardware</label>
<label class="software-label" for="software">💾 software</label>
</div>
<div class="label">
<label class="event-label" for="event" >🍾 event</label>
<label class="art-label" for="art" >🎨 art</label>
<label class="music-label" for="music" >🎵 music</label>
<label class="video-label" for="video" >📺 video</label>
<label class="event-label" for="event" >📅 event</label>
<label class="art-label" for="art" >🖼️ art</label>
<label class="music-label" for="music" >🎶 music</label>
<label class="video-label" for="video" >🎞️ video</label>
</div>
</div>
</details>

View File

@ -1,6 +1,6 @@
=> /images/header.png welcome to zvava.org ({build_info_summary})
hey! i'm sophie (she/her) and i also go by zvava or névtelen. you are currently looking at my brain-out-on-a-table, where i keep a constantly evolving collection of thoughts and projects. the first link goes to the main wiki page where you can filter pages by category
hey! i'm sophie (she/her) and i go by zvava. you are currently looking at my brain-out-on-a-table, where i keep a constantly evolving collection of thoughts and projects the first link goes to the main wiki page where you can filter pages by category. sad girl 4 life
## navigation
=> /wiki/ 📚 wiki
@ -16,6 +16,7 @@ hey! i'm sophie (she/her) and i also go by zvava or névtelen. you are currently
=> https://mk.catgirlsfor.science/@zvava 🔮 fediverse
=> https://matrix.to/#/%23zvavspace%3Acatgirl.cloud 🌐 matrix
=> https://git.zvava.org/zvava 💾 git forge
=> https://keyoxide.org/5386D9E7ED1C49BEE15B9F32074FE2D02D45891C 🔏 keyoxide
=> https://www.buymeacoffee.com/zvavaxox 🍺 buy me a beer!
=> https://webring.xxiivv.com/#icons 🪐 merveilles webring
@ -29,10 +30,9 @@ hey! i'm sophie (she/her) and i also go by zvava or névtelen. you are currently
fediverse: @zvava@mk.catgirlsfor.science
matrix: @zvava:catgirl.cloud
email: z@zvava.org
```
### i also check
```
discord: @zvava
revolt: @zvava#7247
discord: @zvava
```
=> /media/zvava.asc 🔒 public key
wawawawawawa

25
wiki.js
View File

@ -8,6 +8,7 @@ function main() {
switch (scriptArgs[0]) {
case "publish": return publish()
case "make": return make()
case "list": return list()
case "new": return newPage()
case "edit": return edit()
@ -21,6 +22,7 @@ function main() {
" new create a new wiki page\n" +
" edit edit a wiki page\n" +
" rm delete wiki pages\n" +
" make run make script\n\n" +
" publish run publish script\n\n" +
"each command has it's own arguments, to list use -h\n" +
"")
@ -44,11 +46,11 @@ function prependRelevantEmoji(x) {
let e = ""
switch (x) {
case "text": e += "📝"; break
case "info": e += "🧠"; break
case "event": e += "🍾"; break
case "art": e += "🎨"; break
case "music": e += "🎵"; break
case "video": e += "📺"; break
case "info": e += "📑"; break
case "event": e += "📅"; break
case "art": e += "🖼️"; break
case "music": e += "🎶"; break
case "video": e += "🎞️"; break
case "hardware": e += "🔧"; break
case "software": e += "💾"; break
}
@ -70,6 +72,19 @@ function publish() {
print(`publish: cannot run on this platform (${os.platform})`)
}
function make() {
if (scriptArgs.includes("-h") || scriptArgs.includes("--help"))
return print(
"usage: qjs wiki.js make\n\n" +
"literally just runs the make script\n" +
"")
if (canRunExec())
return os.exec(["qjs", "make.js"])
print(`publish: cannot run on this platform (${os.platform})`)
}
function list() {
let args = (scriptArgs[1] || "")
if (args.includes("h"))