From 46b7c21b84434554700a5f4a4072b3bc68b705a3 Mon Sep 17 00:00:00 2001 From: Ruben Date: Sun, 29 Jun 2025 01:03:34 -0500 Subject: [PATCH] update things --- .gitignore | 3 +- _config/filters.js | 43 +++++ _data/eleventyDataSchema.js | 13 ++ _data/metadata.js | 11 ++ _includes/layouts/iceshrimp.njk | 157 ++++++++++++++++++ _includes/layouts/post.njk | 2 +- _includes/layouts/{ => sneexy}/notebook.njk | 13 +- assets/synth.download/sharkey/sharkey.min.css | 2 +- eleventy.config.js | 4 + iceshrimp/iceshrimp.md | 5 + package-lock.json | 25 ++- package.json | 4 +- 12 files changed, 272 insertions(+), 10 deletions(-) create mode 100644 _config/filters.js create mode 100644 _data/eleventyDataSchema.js create mode 100644 _data/metadata.js create mode 100644 _includes/layouts/iceshrimp.njk rename _includes/layouts/{ => sneexy}/notebook.njk (77%) create mode 100644 iceshrimp/iceshrimp.md diff --git a/.gitignore b/.gitignore index d0e4835..08652c7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules/ -_site/ \ No newline at end of file +_site/ +notebook/ \ No newline at end of file diff --git a/_config/filters.js b/_config/filters.js new file mode 100644 index 0000000..3f247fb --- /dev/null +++ b/_config/filters.js @@ -0,0 +1,43 @@ +import { DateTime } from "luxon"; + +export default function(eleventyConfig) { + eleventyConfig.addFilter("readableDate", (dateObj, format, zone) => { + // Formatting tokens for Luxon: https://moment.github.io/luxon/#/formatting?id=table-of-tokens + return DateTime.fromJSDate(dateObj, { zone: zone || "utc" }).toFormat(format || "dd LLLL yyyy"); + }); + + eleventyConfig.addFilter("htmlDateString", (dateObj) => { + // dateObj input: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-date-string + return DateTime.fromJSDate(dateObj, { zone: "utc" }).toFormat('yyyy-LL-dd'); + }); + + // Get the first `n` elements of a collection. + eleventyConfig.addFilter("head", (array, n) => { + if(!Array.isArray(array) || array.length === 0) { + return []; + } + if( n < 0 ) { + return array.slice(n); + } + + return array.slice(0, n); + }); + + // Return the smallest number argument + eleventyConfig.addFilter("min", (...numbers) => { + return Math.min.apply(null, numbers); + }); + + // Return the keys used in an object + eleventyConfig.addFilter("getKeys", target => { + return Object.keys(target); + }); + + eleventyConfig.addFilter("filterTagList", function filterTagList(tags) { + return (tags || []).filter(tag => ["all", "posts"].indexOf(tag) === -1); + }); + + eleventyConfig.addFilter("sortAlphabetically", strings => + (strings || []).sort((b, a) => b.localeCompare(a)) + ); +}; diff --git a/_data/eleventyDataSchema.js b/_data/eleventyDataSchema.js new file mode 100644 index 0000000..ca764ec --- /dev/null +++ b/_data/eleventyDataSchema.js @@ -0,0 +1,13 @@ +import { z } from "zod"; +import { fromZodError } from 'zod-validation-error'; + +export default function(data) { + // Draft content, validate `draft` front matter + let result = z.object({ + draft: z.boolean().or(z.undefined()), + }).safeParse(data); + + if(result.error) { + throw fromZodError(result.error); + } +} diff --git a/_data/metadata.js b/_data/metadata.js new file mode 100644 index 0000000..d5ee0c4 --- /dev/null +++ b/_data/metadata.js @@ -0,0 +1,11 @@ +export default { + title: "Synth Download", + url: "https://synth.download/", + language: "en", + description: "A private tilde/pubnix thing for friends. Beep!", + author: { + name: "Sneexy", + email: "sneexy@synth.download", + url: "https://synth.download/~sneexy/" + } +} diff --git a/_includes/layouts/iceshrimp.njk b/_includes/layouts/iceshrimp.njk new file mode 100644 index 0000000..0d9577f --- /dev/null +++ b/_includes/layouts/iceshrimp.njk @@ -0,0 +1,157 @@ +--- +title: icesynth! +layout: "layouts/base.njk" +permalink: "/iceshrimp/" +--- + + +
+
+ + Welcome! + + +
+ +
+

Hey! Welcome to...

+ +

We're a small (private/for-friends) tilde-not-so-pubnix thing, ran and managed by ~sneexy with some services hosted here and there.

+

There are a few public facing services we run here for general public use, although most services are private or require registration as they are meant for members of Synth.download.

+

Look at the categories below to see what and who we're serving on here.

+

Enjoy your stay! Beep!~

+ +
+ Members +
+

Every user currently registered on the Synth.download tilde will be listed here. Some users may not have pages yet and will lead to a blank page or a 404.

+
+ ~sneexy +
+
+
+
+ Services +
+
+

Redlib (Public)

+

A simple alternative frontend for accessing Reddit content.

+ Go +
+
+

Sharkey

+

Advanced social media software connected to the wider Fediverse (ActivityPub), based on Misskey with many improvements.

+

Accounts from this instance shall be reached via @booping.synth.download

+ Go +
+
+

Iceshrimp

+

Another advanced social media software connected to the wider Fediverse (ActivityPub), provided as an alternative for those who dislike the Misskey experience or prefer the Mastodon compatibility.

+

Accounts from this instance shall be reached via @synth.download

+ Go +
+
+

Ask-js

+

Platform for receiving and answering anonymous questions and answers.

+ Go +
+
+

Forgejo

+

A home for Git repositories.

+ Go +
+
+

PDS

+

Synth.download's Personal Data Server, to be used with the Atmosphere (ATProto) and more specifically, Bluesky.

+
+
+

XMPP

+

A traditional yet feature-full and stable chat protocol, server powered with Ejabberd.

+

+
+ +
+

FreshRSS

+

Online RSS and Atom compatible feed reader.

+ Go +
+
+

Vaultwarden

+

Bitwarden-compatible password manager with 2FA support and all that good stuff.

+ Go +
+
+

ZITADEL

+

Our authenticator to access multiple services using one account... or an attempt to. Currently only used for FreshRSS and Forgejo, and hoping to expand more with this.

+ Go +
+
+

A Dark Room

+

Just a fun mirror of A Dark Room, a minimalist and dark text adventure-like game.

+ Go +
+
+
+
+ Questions & Answers +
+

As answered by ~sneexy, the sysadmin of Synth.download.

+
+

Q: How do I join this tilde/pubnix/these services?

+
+

A: I pretty much just need to know you/the one reading this enough. I'll choose whether or not you'll be let in, trying to "Speedrun" getting close to me will not get you in. Massive bonus points if we're already friends/established mutuals!

+

If you'd like to try asking, do so! Contact synth@synth.download* with the following:

+
    +
  • Making it clear who you are (links to any profiles or websites)
  • +
  • Your public SSH key (that will be used to login to the pubnix - optional if you don't want/need this)
  • +
  • Listing the services you want (as most of them aren't connected to one account and will require manually registration on your end)
  • +
  • A creature sound (optional)
  • +
+

You'll get a response with how to log in if you've been accepted!

+

*Depending on the mailserver/service you use, you may not be able to send mail to synth.download. In this case, feel free to poke at me (y'know, ~sneexy) anywhere else. You know where if we're moots.

+

Note: You don't have to register for the Synth.download tilde/pubnix if you're just looking to register for one of our services (like our Sharkey or Iceshrimp instance). Feel free to just ask directly if that's the case! The same restrictions as if you were going to register for the tilde/pubnix still apply though.

+
+
+

Q: I sent a registration thing and it's been a while, what's up?

+
+

A: Either A: You've been denied, and I won't explain why due to having a low social battery when it comes to explaining things or B: You have been accepted/considered but I do registration and everything manually (Yes, automation would be nice, but also seems overkill for a private thing that won't get much outside traction), so it may take a while for me to finish up the process for you to be able to get in.

+

In either case, try poking at me directly and I may respond depending on the end case.

+
+
+

Q: Is information on this page up to date?

+
+

A: Uh... Probably? It should be, although yes, it should be noted that everything on this page is static. I manually update the information listed here for everything. I just haven't bothered setting up any sort of dynamic stuff.

+
+
+

Q: Why something so fancy for something private?

+
+

A: Why not? I'm having fun making this site. Might as well put some extra information on here, even if it'll probably be private and small forever. (Although - Things can always change! Who knows if I decide to expand publicly or something.)

+
+
+

Q: Why are some your services behind Anubis??? Don't you know it's so easy to bypass and it's stupid and hurts real users??? You must be gay and dumb and fat and stupid.

+
+

A: Honestly, Anubis is just sort of a pre-caution specifically for some of our services that are easily targetable for/by scrapers. Considering how recently the Open Web[TM] has seen so many attacks from mass AI scraping that essentially caused multiple (and still ongoing) DDOS'es.

+

I know Anubis is "Easy" to bypass but the whole point of it is to try and directly tell scrapers/bots acting in malicious fate that try to be regular browser to get away with everything to fuck off. I don't want to keep having to manually fight back and keep blocking new IPs or do anything else when Anubis is an existing, easy to set up and overall effective solution, as seen by everyone else running it.

+

Currently, anyways. At some point scrapers will become smart enough that the way Anubis works won't be effective, but currently it still is and a temporary solution to protect ourselves is better than nothing. And also Anubis is somewhat temporary until I stop being lazy to migrate to something else.

+
+
+

Q: Merp!

+
+

A: Beep!

+
+
+
+
+
\ No newline at end of file diff --git a/_includes/layouts/post.njk b/_includes/layouts/post.njk index 76028f2..e638a4f 100644 --- a/_includes/layouts/post.njk +++ b/_includes/layouts/post.njk @@ -25,7 +25,7 @@ permalink: "/notebook/{{ date }}-{{ title | slugify }}/"

title: {{ title or metadata.title }}

{%- set tagUrl %}/tags/{{ tags | slugify }}/{% endset %} -

tags: {{ tags }}{%- if not loop.last %}{% endif %}

+

tags: {%- for tag in tags | filterTagList %} {%- set tagUrl %}/tags/{{ tag | slugify }}/{% endset %}

{%- if not loop.last %}, {% endif %}

diff --git a/_includes/layouts/notebook.njk b/_includes/layouts/sneexy/notebook.njk similarity index 77% rename from _includes/layouts/notebook.njk rename to _includes/layouts/sneexy/notebook.njk index 15e1ce6..0f5b4dc 100644 --- a/_includes/layouts/notebook.njk +++ b/_includes/layouts/sneexy/notebook.njk @@ -31,14 +31,17 @@ permalink: "/notebook/"
test - {%- for other in collections.other %} + {%- for knowledgebase in collections.knowledgebase %}
-

{{ other.data.title }}

+

{{ knowledgebase.data.title }}

- + {%- for tag in tags | filterTagList %} + {%- set tagUrl %}/tags/{{ tag | slugify }}/{% endset %} + {%- if not loop.last %}, {% endif %} + {%- endfor %}

-

{{ other.data.description }}

- read more +

{{ knowledgebase.data.description }}

+ read more
{%- endfor %} diff --git a/assets/synth.download/sharkey/sharkey.min.css b/assets/synth.download/sharkey/sharkey.min.css index 2e18b78..89279f0 100644 --- a/assets/synth.download/sharkey/sharkey.min.css +++ b/assets/synth.download/sharkey/sharkey.min.css @@ -1 +1 @@ -#sharkey_app {[class^="visitor-root-"] {[class^="visitor-main-"] {[class^="visitor-homeButton-"] {background: var(--MI_THEME-accent) !important;color: var(--MI_THEME-fgOnAccent) !important;}[class^="visitor-content-"] {[class^="pages-welcome-entrance-a-shape1-"], [class^="pages-welcome-entrance-a-shape2-"], [class^="pages-welcome-timeline-root-"] {display: none;}[class^="pages-welcome-entrance-a-logoWrapper-"] {[class^="pages-welcome-entrance-a-poweredBy-"] {color: var(--MI_THEME-fg);}[class^="pages-welcome-entrance-a-misskey-"] {width: 120px !important;}}[class^="pages-welcome-entrance-a-logoWrapper-"]::before {-webkit-backdrop-filter: var(--MI-blur, blur(15px));backdrop-filter: var(--MI-blur, blur(15px));background: var(--MI_THEME-acrylicPanel);border-radius: var(--MI-radius-ellipse);content: '';height: 6.5rem;left: -1rem;position: absolute;top: -1rem;width: 10.6rem;z-index: -5;}[class^="MkFeaturedPhotos-root-"] {animation: animatebg 100s linear infinite;background-image: url("https://cdn.booping.synth.download/assets/synth+grid+bg.png") !important;background-repeat: repeat;background-size: auto;height: 100% !important;left: 0 !important;opacity: .8;top: 0 !important;width: 100% !important;}[class^="pages-welcome-entrance-a-contents-"] {margin-left: auto !important;margin-right: auto !important;padding: 130px 0;[class^="MkVisitorDashboard-root-"]::before {-webkit-backdrop-filter: var(--MI-blur, blur(15px));backdrop-filter: var(--MI-blur, blur(15px));background: var(--MI_THEME-acrylicPanel);border-radius: var(--MI-radius-ellipse);content: '';height: 129.1rem;left: -1.7rem;position: absolute;top: .5rem;transition: padding .2s;width: 34.1rem;}[class^="MkVisitorDashboard-tl-"] {[class^="MkVisitorDashboard-tlBody-"] {height: 50rem !important;}}}[class^="pages-welcome-entrance-a-federation-"] {bottom: unset !important;top: 16px !important;z-index: 50 !important;}}}[class^="visitor-side-"] {background: linear-gradient(var(--MI_THEME-bg), var(--MI_THEME-accent));[class^="visitor-banner-"] {animation: animatebg 100s linear infinite;background-image: url("https://cdn.booping.synth.download/assets/synth+grid+bg.png") !important;background-repeat: repeat;background-size: auto;height: 100% !important;left: 0 !important;opacity: .8;top: 0 !important;width: 100% !important;}}@media (prefers-reduced-motion: reduce) {[class^="visitor-side-"] [class^="visitor-banner-"] {animation: unset !important;}[class^="visitor-main-"] [class^="visitor-content-"] [class^="MkFeaturedPhotos-root-"] {animation: unset !important;}}}[class^="SkNote-renote-"] {[class^="_noSelect MkAvatar-root-"] {display: unset !important;}}[class^="_button MkReactionsViewer-reaction-root-"]:not([class*="MkReactionsViewer-reaction-canToggle-"]) {border: solid 1px var(--MI_THEME-divider);}[class^="SkNoteSub-body-"] {[class^="SkNoteHeader-classicRoot-"] {padding-bottom: .3rem;}[class^="MkReactionsViewer-root-"] {padding-top: .6rem;}}}@keyframes animatebg {0% {background-position: 0px 0px;}100% {background-position: -960px -960px;}} \ No newline at end of file +#sharkey_app{& [class^=visitor-root-]{& [class^=visitor-main-]{& [class^=visitor-homeButton-]{background:var(--MI_THEME-accent)!important;color:var(--MI_THEME-fgOnAccent)!important}& [class^=visitor-content-]{& [class^=pages-welcome-entrance-a-shape1-],& [class^=pages-welcome-entrance-a-shape2-],& [class^=pages-welcome-timeline-root-]{display:none}& [class^=pages-welcome-entrance-a-logoWrapper-]{& [class^=pages-welcome-entrance-a-poweredBy-]{color:var(--MI_THEME-fg)}& [class^=pages-welcome-entrance-a-misskey-]{width:120px!important}}& [class^=pages-welcome-entrance-a-logoWrapper-]:before{backdrop-filter:var(--MI-blur,blur(15px));background:var(--MI_THEME-acrylicPanel);border-radius:var(--MI-radius-ellipse);content:"";z-index:-5;width:10.6rem;height:6.5rem;position:absolute;top:-1rem;left:-1rem}& [class^=MkFeaturedPhotos-root-]{opacity:.8;background-repeat:repeat;background-size:auto;animation:100s linear infinite animatebg;background-image:url(https://cdn.booping.synth.download/assets/synth+grid+bg.png)!important;width:100%!important;height:100%!important;top:0!important;left:0!important}& [class^=pages-welcome-entrance-a-contents-]{padding:130px 0;margin-left:auto!important;margin-right:auto!important;& [class^=MkVisitorDashboard-root-]:before{backdrop-filter:var(--MI-blur,blur(15px));background:var(--MI_THEME-acrylicPanel);border-radius:var(--MI-radius-ellipse);content:"";width:34.1rem;height:129.1rem;transition:padding .2s;position:absolute;top:.5rem;left:-1.7rem}& [class^=MkVisitorDashboard-tl-]{& [class^=MkVisitorDashboard-tlBody-]{height:50rem!important}}}& [class^=pages-welcome-entrance-a-federation-]{bottom:unset!important;z-index:50!important;top:16px!important}}}& [class^=visitor-side-]{background:linear-gradient(var(--MI_THEME-bg),var(--MI_THEME-accent));& [class^=visitor-banner-]{opacity:.8;background-repeat:repeat;background-size:auto;animation:100s linear infinite animatebg;background-image:url(https://cdn.booping.synth.download/assets/synth+grid+bg.png)!important;width:100%!important;height:100%!important;top:0!important;left:0!important}}@media (prefers-reduced-motion:reduce){& [class^=visitor-side-] [class^=visitor-banner-],& [class^=visitor-main-] [class^=visitor-content-] [class^=MkFeaturedPhotos-root-]{animation:unset!important}}}& [class^=SkNote-renote-]{& [class^=_noSelect\ MkAvatar-root-]{display:unset!important}}& [class^=_button\ MkReactionsViewer-reaction-root-]:not([class*=MkReactionsViewer-reaction-canToggle-]){border:solid 1px var(--MI_THEME-divider)}& [class^=SkNoteSub-body-]{& [class^=SkNoteHeader-classicRoot-]{padding-bottom:.3rem}& [class^=MkReactionsViewer-root-]{padding-top:.6rem}}}@keyframes animatebg{0%{background-position:0 0}to{background-position:-960px -960px}} \ No newline at end of file diff --git a/eleventy.config.js b/eleventy.config.js index 4e19f5f..84fec24 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -1,11 +1,15 @@ import { minify } from "terser"; import { transform } from "lightningcss"; import eleventyNavigationPlugin from "@11ty/eleventy-navigation"; +import pluginFilters from "./_config/filters.js"; export default function(eleventyConfig) { eleventyConfig.addPassthroughCopy("assets/"); eleventyConfig.addPassthroughCopy({ "sneexy/notebook/": "~sneexy/notebook/" }); // notebook page generated by quartz seperately - see https://forged.synth.download/sneexy/notebook + // our custom filters + eleventyConfig.addPlugin(pluginFilters); + eleventyConfig.addFilter("cssmin", function (code) { const result = transform({ code: Buffer.from(code, 'utf-8'), diff --git a/iceshrimp/iceshrimp.md b/iceshrimp/iceshrimp.md new file mode 100644 index 0000000..2e47866 --- /dev/null +++ b/iceshrimp/iceshrimp.md @@ -0,0 +1,5 @@ +--- +title: icesynth! +layout: "layouts/iceshrimp.njk" +--- + diff --git a/package-lock.json b/package-lock.json index d9bcd31..e71cd96 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,9 @@ "@11ty/eleventy-navigation": "^1.0.4", "@11ty/eleventy-plugin-rss": "^2.0.4", "lightningcss": "^1.30.1", - "terser": "^5.42.0" + "terser": "^5.42.0", + "zod": "^3.25.67", + "zod-validation-error": "^3.5.2" } }, "node_modules/@11ty/dependency-tree": { @@ -1934,6 +1936,27 @@ "optional": true } } + }, + "node_modules/zod": { + "version": "3.25.67", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.67.tgz", + "integrity": "sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-validation-error": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-3.5.2.tgz", + "integrity": "sha512-mdi7YOLtram5dzJ5aDtm1AG9+mxRma1iaMrZdYIpFO7epdKBUwLHIxTF8CPDeCQ828zAXYtizrKlEJAtzgfgrw==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "zod": "^3.25.0" + } } } } diff --git a/package.json b/package.json index f641dff..2098382 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,8 @@ "@11ty/eleventy-navigation": "^1.0.4", "@11ty/eleventy-plugin-rss": "^2.0.4", "lightningcss": "^1.30.1", - "terser": "^5.42.0" + "terser": "^5.42.0", + "zod": "^3.25.67", + "zod-validation-error": "^3.5.2" } }