diff options
-rw-r--r-- | .well-known/host-meta.xml | 4 | ||||
-rw-r--r-- | _comments.sh | 3 | ||||
-rw-r--r-- | _config.yml | 5 | ||||
-rw-r--r-- | _data/news.yml | 2 | ||||
-rw-r--r-- | _includes/commentNotice.html | 35 | ||||
-rw-r--r-- | _includes/header.html | 1 | ||||
-rw-r--r-- | _layouts/postlist.html | 3 | ||||
-rw-r--r-- | _posts/2021-03-23-winvm.md | 1 | ||||
-rw-r--r-- | _posts/2021-04-25-networkstuff.md | 1 | ||||
-rw-r--r-- | _posts/2021-06-03-fakir-teardown.md | 1 | ||||
-rw-r--r-- | _posts/2021-06-27-wpa-enterprise-unifi.md | 1 | ||||
-rw-r--r-- | _posts/2021-09-22-problems-updating-proxmox.md | 1 | ||||
-rw-r--r-- | _posts/2021-10-28-rant-devuan-upgrade.md | 1 | ||||
-rw-r--r-- | _posts/2022-01-20-server-stuff.md | 2 | ||||
-rw-r--r-- | _posts/2022-04-03-backporting-pipewire-in-devuan.md | 2 | ||||
-rw-r--r-- | _posts/2024-09-04-convention-report-east-12-2024.md | 1 | ||||
-rw-r--r-- | assets/main.scss | 6 | ||||
-rw-r--r-- | assets/mscomm/comments.js | 311 | ||||
-rw-r--r-- | assets/mscomm/styles.css | 92 | ||||
-rw-r--r-- | dn42.md | 2 | ||||
-rw-r--r-- | projects.md | 31 | ||||
-rw-r--r-- | readme.txt | 3 |
22 files changed, 497 insertions, 12 deletions
diff --git a/.well-known/host-meta.xml b/.well-known/host-meta.xml new file mode 100644 index 0000000..3f156a0 --- /dev/null +++ b/.well-known/host-meta.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> + <XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"> + <Link rel="lrdd" type="application/json" template="https://blog.uvokchee.de/.well-known/webfinger?resource={uri}"></Link> + </XRD>
\ No newline at end of file diff --git a/_comments.sh b/_comments.sh new file mode 100644 index 0000000..2dc6c85 --- /dev/null +++ b/_comments.sh @@ -0,0 +1,3 @@ +#!/bin/sh +#scp hetzner:/var/www/hatsu/hatsu.sqlite3 . +sqlite3 -box hatsu.sqlite3 'SELECT id, in_reply_to_root FROM post where in_reply_to IS NOT NULL;' diff --git a/_config.yml b/_config.yml index 80f282c..cc4ac74 100644 --- a/_config.yml +++ b/_config.yml @@ -71,4 +71,7 @@ autopages: collections: enabled: false -cssversion: "2023120301" +cssversion: "2024010301" + +feed: + posts_limit: 20 diff --git a/_data/news.yml b/_data/news.yml index 4684514..0e64621 100644 --- a/_data/news.yml +++ b/_data/news.yml @@ -2,7 +2,7 @@ content: >- <div> <div style="font-weight: bold">You don't seem to be using an ad blocker.</div> - <div>Please consider installing one.</div> + <div>Please consider installing one. I would recommend uBlock Origin.</div> </div> - id: news1 content: >- diff --git a/_includes/commentNotice.html b/_includes/commentNotice.html index b1be501..a46dadf 100644 --- a/_includes/commentNotice.html +++ b/_includes/commentNotice.html @@ -1,19 +1,44 @@ <section> + {% assign base_url = 'https://blog.uvokchee.de/notice/' %} + {% assign url = page.url %} + {% assign domain = 'https://blog.uvokchee.de' %} + {% assign full_url = domain | append: page.url %} + {% capture encoded_url %}{{ full_url | base64_encode }}{% endcapture %} + {% assign src_url = base_url | append: encoded_url %} + <h2>Kommentare / Comments</h2> - <p>Kommentare werden von mir selbst auf einem anderen Server über <a href="https://isso-comments.de/">Isso</a> gehostet.</p> + <h3>Isso</h3> + + <p>Kommentare werden von mir selbst auf einem anderen Server über <a href="https://isso-comments.de/">Isso</a> + gehostet.</p> <p>Comments are hosted by myself on another server, powered by <a href="https://isso-comments.de/">Isso</a>.</p> - <script data-isso="//c.uvokchee.de/" - data-isso-require-author=true - data-isso-vote=false + <script data-isso="//c.uvokchee.de/" data-isso-require-author=true data-isso-vote=false src="//c.uvokchee.de/js/embed.min.js"></script> <section id="isso-thread"> {% if jekyll.environment == "development" %} {% include testc.html %} {% endif %} </section> + + <h3>Fediverse</h3> + <script type="module"> + import Comments from '{{ "/assets/mscomm/comments.js" | relative_url }}' + export function loadComments() { + document.getElementById('load-comments-btn').remove(); + customElements.define('oom-comments', Comments); + } + window.loadComments = loadComments; + </script> + <link rel="stylesheet" href="{{ "/assets/mscomm/styles.css" | relative_url }}?v={{ site.cssversion }}"> + <oom-comments src="{{ src_url }}"> + <button id="load-comments-btn" class="load-comments-btn" onclick="loadComments()">Load Comments from + ActivityPub</button> + </oom-comments> + <p style="margin-top: 1em"><a href="{{ src_url }}">ActivityPub-Link</a></p> + <noscript> <p>Um Kommentare zu hinterlassen, ist leider JavaScript nötig.</p> - <p>Unfortunately, JavaScript is required to leave comments</p> + <p>Unfortunately, JavaScript is required to leave comments.</p> </noscript> </section> diff --git a/_includes/header.html b/_includes/header.html index 492dcd5..86e812e 100644 --- a/_includes/header.html +++ b/_includes/header.html @@ -13,7 +13,6 @@ </label> <div class="trigger" lang="en"> {% include_cached navlinks.html %} - <a class="page-link" href="https://uvokchee.de/wiki/">Wiki</a> <a class="rss-subscribe page-link" href="{{ "/feed.xml" | relative_url }}">RSS feed</a> </div> </nav> diff --git a/_layouts/postlist.html b/_layouts/postlist.html index 67a1d48..52d07df 100644 --- a/_layouts/postlist.html +++ b/_layouts/postlist.html @@ -39,6 +39,9 @@ layout: default {%- elsif site.show_excerpts -%} {{ post.excerpt }} {%- assign showsep = true -%} + {%- elsif post.description -%} + {{ post.description }} + {%- assign showsep = true -%} {%- endif -%} </div> </li> diff --git a/_posts/2021-03-23-winvm.md b/_posts/2021-03-23-winvm.md index 528d636..3ee73f4 100644 --- a/_posts/2021-03-23-winvm.md +++ b/_posts/2021-03-23-winvm.md @@ -4,6 +4,7 @@ title: Windows VM under Devuan with QEMU / libvirt date: 2021-03-23 20:32 +0100 categories: tech description: How to run a Windows VM under Devuan with QEMU / libvirt +lang: en --- So, I'm running Devuan Beowulf (Debian Buster based). Recently, I was in the need of running a diff --git a/_posts/2021-04-25-networkstuff.md b/_posts/2021-04-25-networkstuff.md index 3152f3f..7b2cff6 100644 --- a/_posts/2021-04-25-networkstuff.md +++ b/_posts/2021-04-25-networkstuff.md @@ -4,6 +4,7 @@ title: Network stuff date: 2021-04-25 21:50 +0200 categories: tech description: "I do some experiments with networking stuff. Proxmox and running OpenWRT in a VM." +lang: en --- Been a long time. diff --git a/_posts/2021-06-03-fakir-teardown.md b/_posts/2021-06-03-fakir-teardown.md index 1de8bf9..75f609d 100644 --- a/_posts/2021-06-03-fakir-teardown.md +++ b/_posts/2021-06-03-fakir-teardown.md @@ -3,6 +3,7 @@ layout: post title: Fakir Robert Teardown date: 2021-06-03 20:39 +0200 description: Ein Teardown eines alten Staubsauger-Roboters +lang: de --- Da ich mir demnächst mal einen neuen gebrauchten Saugroboter holen werde, diff --git a/_posts/2021-06-27-wpa-enterprise-unifi.md b/_posts/2021-06-27-wpa-enterprise-unifi.md index 61c49a7..36b9e6e 100644 --- a/_posts/2021-06-27-wpa-enterprise-unifi.md +++ b/_posts/2021-06-27-wpa-enterprise-unifi.md @@ -4,6 +4,7 @@ title: WPA Enterprise mit Unifi Access Points date: 2021-06-27 20:28 +0200 categories: tech description: "Wie man WPA Enterprise einrichtet, mit Unifi WiFi Access Points und Software, die unter Linux läuft" +lang: de --- Ich hab mal einen kurzen Artikel geschrieben, wie man WPA Enterprise diff --git a/_posts/2021-09-22-problems-updating-proxmox.md b/_posts/2021-09-22-problems-updating-proxmox.md index 3885b79..7353d67 100644 --- a/_posts/2021-09-22-problems-updating-proxmox.md +++ b/_posts/2021-09-22-problems-updating-proxmox.md @@ -2,6 +2,7 @@ layout: post title: Network gone after updating Proxmox date: 2021-09-22 20:59 +0200 +lang: en --- So, after upgrading Proxmox from version 6.x to 7.x, the network diff --git a/_posts/2021-10-28-rant-devuan-upgrade.md b/_posts/2021-10-28-rant-devuan-upgrade.md index 100dd3b..c3da9b0 100644 --- a/_posts/2021-10-28-rant-devuan-upgrade.md +++ b/_posts/2021-10-28-rant-devuan-upgrade.md @@ -3,6 +3,7 @@ layout: post title: 'Rant: Devuan Upgrade' date: 2021-10-28 19:58 +0200 categories: tech +lang: en --- Gna. So I upgraded my Devuan installation from Beowulf to Chimaera. Process was a bit tricky, diff --git a/_posts/2022-01-20-server-stuff.md b/_posts/2022-01-20-server-stuff.md index 40d39a1..f5f053f 100644 --- a/_posts/2022-01-20-server-stuff.md +++ b/_posts/2022-01-20-server-stuff.md @@ -3,7 +3,7 @@ layout: post title: Server stuff date: 2022-01-20 18:55 +0100 category: tech -language: en +lang: en description: "I experiment with SPF, DMARC and DKIM." --- diff --git a/_posts/2022-04-03-backporting-pipewire-in-devuan.md b/_posts/2022-04-03-backporting-pipewire-in-devuan.md index 1d20df2..c0a9fe3 100644 --- a/_posts/2022-04-03-backporting-pipewire-in-devuan.md +++ b/_posts/2022-04-03-backporting-pipewire-in-devuan.md @@ -3,7 +3,7 @@ layout: post title: Backporting Pipewire in Devuan date: 2022-04-03 17:45 +0200 category: tech -language: en +lang: en --- **Update 2023-09-07**: With Devuan Daedelus Pipewire is in the diff --git a/_posts/2024-09-04-convention-report-east-12-2024.md b/_posts/2024-09-04-convention-report-east-12-2024.md index 7c71898..31785a8 100644 --- a/_posts/2024-09-04-convention-report-east-12-2024.md +++ b/_posts/2024-09-04-convention-report-east-12-2024.md @@ -3,6 +3,7 @@ layout: post title: 'Convention Report: EAST 12 (2024)' date: 2024-09-04 20:00 +0200 description: My convention report of the furry convention "EAST 12" in 2024 +lang: en --- It's time for another convention report. I've been going to the EAST convention since EAST 7 (except EAST 10, which was diff --git a/assets/main.scss b/assets/main.scss index ff45870..4ff4a71 100644 --- a/assets/main.scss +++ b/assets/main.scss @@ -53,7 +53,6 @@ a:visited { background: #eeeeee; margin-bottom: 1em; position: relative; - z-index: -1; } .banner-close-button { @@ -67,3 +66,8 @@ hr.postsep { margin: auto; margin-bottom: 1em; } + +/* site nav above news items */ +.site-nav { + z-index: 10; +} diff --git a/assets/mscomm/comments.js b/assets/mscomm/comments.js new file mode 100644 index 0000000..57b9793 --- /dev/null +++ b/assets/mscomm/comments.js @@ -0,0 +1,311 @@ +// © https://phosphoricons.com/ +export const icons = { + reblog: + `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 256 256" fill="none" stroke="currentColor" stroke-width="24"><polyline points="200 88 224 64 200 40"/><path d="M32,128A64,64,0,0,1,96,64H224"/><polyline points="56 168 32 192 56 216"/><path d="M224,128a64,64,0,0,1-64,64H32"/></svg>`, + favourite: + `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 256 256" fill="currentColor"><path d="M240,94c0,70-103.79,126.66-108.21,129a8,8,0,0,1-7.58,0C119.79,220.66,16,164,16,94A62.07,62.07,0,0,1,78,32c20.65,0,38.73,8.88,50,23.89C139.27,40.88,157.35,32,178,32A62.07,62.07,0,0,1,240,94Z"/></svg>`, + author: + `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 256 256" fill="currentColor" class="comment-author"><path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm45.66,85.66-56,56a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L112,148.69l50.34-50.35a8,8,0,0,1,11.32,11.32Z"></path></svg>`, + + // @ https://simpleicons.org/ + mastodon: + `<svg role="img" width="16" height="16" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Mastodon</title><path d="M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z"/></svg>`, + + pleroma: + `<svg role="img" width="16" height="16" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Pleroma</title><path d="M6.36 0A1.868 1.868 0 004.49 1.868V24h5.964V0zm7.113 0v12h4.168a1.868 1.868 0 001.868-1.868V0zm0 18.036V24h4.168a1.868 1.868 0 001.868-1.868v-4.096Z"/></svg>`, + + bluesky: + `<svg role="img" width="16" height="16" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Bluesky</title><path d="M12 10.8c-1.087-2.114-4.046-6.053-6.798-7.995C2.566.944 1.561 1.266.902 1.565.139 1.908 0 3.08 0 3.768c0 .69.378 5.65.624 6.479.815 2.736 3.713 3.66 6.383 3.364.136-.02.275-.039.415-.056-.138.022-.276.04-.415.056-3.912.58-7.387 2.005-2.83 7.078 5.013 5.19 6.87-1.113 7.823-4.308.953 3.195 2.05 9.271 7.733 4.308 4.267-4.308 1.172-6.498-2.74-7.078a8.741 8.741 0 0 1-.415-.056c.14.017.279.036.415.056 2.67.297 5.568-.628 6.383-3.364.246-.828.624-5.79.624-6.478 0-.69-.139-1.861-.902-2.206-.659-.298-1.664-.62-4.3 1.24C16.046 4.748 13.087 8.687 12 10.8Z"/></svg>`, +}; + +export default class SocialComments extends HTMLElement { + comments = {}; + + async connectedCallback() { + const lang = this.closest("[lang]")?.lang || navigator.language || "en"; + + this.dateTimeFormatter = new Intl.DateTimeFormat(lang, { + dateStyle: "medium", + timeStyle: "short", + }); + + const mastodon = this.getAttribute("mastodon") || this.getAttribute("src"); + const bluesky = this.getAttribute("bluesky"); + + await Promise.all([ + mastodon && this.#fetchMastodon(new URL(mastodon)), + bluesky && this.#fetchBluesky(new URL(bluesky)), + ]); + + this.refresh(); + } + + refresh() { + const comments = [ + ...this.comments.mastodon || [], + ...this.comments.bluesky || [], + ].sort( + (a, b) => new Date(a.createdAt) - new Date(b.createdAt), + ); + + if (comments.length) { + this.innerHTML = ""; + this.render(this, comments); + } + } + + async #fetchBluesky(url) { + const { pathname } = url; + + const [, handle, rkey] = pathname.match( + /\/profile\/([\w\.]+)\/post\/(\w+)/, + ); + + if (!handle || !rkey) { + return; + } + + const options = { + ttl: Number(this.getAttribute("cache") || 0), + }; + + const didData = await fetchJSON( + `https://public.api.bsky.app/xrpc/com.atproto.identity.resolveHandle?handle=${handle}`, + options, + ); + const uri = `at://${didData.did}/app.bsky.feed.post/${rkey}`; + + this.comments.bluesky = dataFromBluesky( + await fetchJSON( + `https://public.api.bsky.app/xrpc/app.bsky.feed.getPostThread?uri=${uri}`, + options, + ), + ); + } + + async #fetchMastodon(url) { + const { origin, pathname } = url; + let id; + + const source = pathname.includes("/notice/") ? "pleroma" : "mastodon"; + + if (source === "pleroma") { + [, id] = pathname.match(/^\/notice\/([^\/?#]+)/); + } else { + [, id] = pathname.match(/\/(\d+)$/); + } + + if (!id) { + return; + } + + const token = this.getAttribute("token"); + const options = { + ttl: Number(this.getAttribute("cache") || 0), + }; + if (token) { + options.headers = { + Authorization: `Bearer ${token}`, + }; + } + + const user = url.pathname.split("/")[1]; + const author = `${user}@${url.hostname}`; + + const comments = dataFromMastodon( + await fetchJSON( + new URL(`${origin}/api/v1/statuses/${id}/context`), + options, + ), + author, + source, + ); + + this.comments.mastodon = comments.filter((comment) => + comment.parent === id + ); + } + + render(container, replies) { + const ul = document.createElement("ul"); + + for (const reply of replies) { + const comment = document.createElement("li"); + comment.innerHTML = this.renderComment(reply); + + if (reply.replies.length) { + this.render(comment, reply.replies); + } + ul.appendChild(comment); + } + + container.appendChild(ul); + } + + renderComment(comment) { + return ` + <article class="comment" id="comment-${comment.id}"> + <footer class="comment-footer"> + <a href="${comment.author.url}" class="comment-user"> + <img class="comment-avatar" src="${comment.author.avatar}" alt="${comment.author.alt}'s avatar" width="200" height="200"> + ${comment.isMine ? icons.author : ""} + <strong class="comment-username"> + ${comment.author.name} + </strong> + <em class="comment-useraddress">${comment.author.handler}</em> + </a> + <a href="${comment.url}" class="comment-address"> + <time class="comment-time" title="${comment.createdAt.toISOString()}"> + ${this.dateTimeFormatter.format(comment.createdAt)} + ${icons[comment.source]} + </time> + </a> + </footer> + <div class="comment-body"> + ${comment.content} + + <p class="comment-counts"> + ${ + comment.boosts ? `<span>${icons.reblog} ${comment.boosts}</span>` : "" + } + ${ + comment.likes ? `<span>${icons.favourite} ${comment.likes}</span>` : "" + } + </p> + </div> + </article> + `; + } +} + +function formatEmojis(html, emojis) { + emojis.forEach(({ shortcode, static_url, url }) => { + html = html.replace( + `:${shortcode}:`, + `<picture> + <source srcset="${url}" media="(prefers-reduced-motion: no-preference)"> + <img src="${static_url}" alt=":${shortcode}:" title=":${shortcode}:" width="16" height="16"> + </picture>`, + ); + }); + return html; +} + +async function fetchJSON(url, options = {}) { + const headers = new Headers(); + + if (options.headers) { + for (const [key, value] of Object.entries(options.headers)) { + headers.set(key, value); + } + } + + if (typeof caches === "undefined") { + return await (await fetch(url), { headers }).json(); + } + + const cache = await caches.open("mastodon-comments"); + let cached = await cache.match(url); + + if (cached && options.ttl) { + const cacheTime = new Date(cached.headers.get("x-cached-at")); + const diff = Date.now() - cacheTime.getTime(); + + if (diff <= options.ttl * 1000) { + return await cached.json(); + } + } + + try { + const response = await fetch(url, { headers }); + const body = await response.json(); + + cached = new Response(JSON.stringify(body)); + cached.headers.set("x-cached-at", new Date()); + cached.headers.set("content-type", "application/json; charset=utf-8"); + await cache.put(url, cached); + return body; + } catch { + if (cached) { + return await cached.json(); + } + } +} + +function dataFromMastodon(data, author, source) { + const comments = new Map(); + + // Transform data to a more usable format + for (const comment of data.descendants) { + if (comment.visibility !== "public") { + continue; + } + + const { account } = comment; + const handler = `@${account.username}@${new URL(account.url).hostname}`; + comments.set(comment.id, { + id: comment.id, + isMine: author === handler, + source, + url: comment.url, + parent: comment.in_reply_to_id, + createdAt: new Date(comment.created_at), + content: formatEmojis(comment.content, comment.emojis), + author: { + name: formatEmojis(account.display_name, account.emojis), + handler, + url: account.url, + avatar: account.avatar_static, + alt: account.display_name, + }, + boosts: comment.reblogs_count, + likes: comment.favourites_count, + replies: [], + }); + } + + // Group comments by parent + for (const comment of comments.values()) { + if (comment.parent && comments.has(comment.parent)) { + comments.get(comment.parent).replies.push(comment); + } + } + + return Array.from(comments.values()); +} + +function dataFromBluesky(data) { + const { thread } = data; + + return blueskyComments( + thread.post.author.did, + thread.post.cid, + thread.replies, + ); +} + +function blueskyComments(author, parent, comments) { + return comments.map((reply) => { + const { post, replies } = reply; + const rkey = post.uri.split("/").pop(); + return { + id: post.cid, + isMine: post.author.did === author, + source: "bluesky", + url: `https://bsky.app/profile/${post.author.handle}/post/${rkey}`, + parent, + createdAt: new Date(post.record.createdAt), + content: post.record.text, + author: { + name: post.author.displayName, + handler: post.author.handle, + url: `https://bsky.app/profile/${post.author.handle}`, + avatar: post.author.avatar, + alt: post.author.displayName, + }, + boosts: post.repostCount, + likes: post.likeCount, + replies: blueskyComments(author, post.cid, replies || []), + }; + }); +} diff --git a/assets/mscomm/styles.css b/assets/mscomm/styles.css new file mode 100644 index 0000000..61d4d0d --- /dev/null +++ b/assets/mscomm/styles.css @@ -0,0 +1,92 @@ +oom-comments { + display: block; + /*padding: 2em;*/ +} +oom-comments ul { + list-style: none; + margin: 0; + padding: 0; +} +oom-comments li { + margin: 32px 0; +} +oom-comments article { + max-width: 600px; +} +oom-comments ul ul { + margin-left: 64px; +} +oom-comments .comment-avatar { + width: 50px; + height: 50px; + border-radius: 6px; + float: left; + margin-right: 14px; + box-shadow: 0 0 1px #0009; +} +oom-comments .comment-user { + color: currentColor; + text-decoration: none; + display: block; + position: relative; +} +oom-comments .comment-author { + position: absolute; + left: 35px; + top: 35px; + background: white; + border-radius: 50%; + width: 20px; + height: 20px; + color: gray; +} +oom-comments .comment-user:hover .comment-username { + text-decoration: underline; +} +oom-comments .comment-username { + margin-right: 0.5em; +} +oom-comments .comment-useraddress { + color: gray; + font-size: small; + font-style: normal; +} +oom-comments .comment-time { + font-size: small; + display: flex; + align-items: center; + column-gap: 0.4em; +} +oom-comments .comment-time svg { + width: 1em; + height: 1em; + fill: gray; +} +oom-comments .comment-address { + color: currentColor; + text-decoration: none; + display: block; + margin-top: 0.25em; +} +oom-comments .comment-address:hover { + text-decoration: underline; +} +oom-comments .comment-body { + margin-top: 0.5em; + margin-left: 64px; + line-height: 1.5; +} +oom-comments .comment-body p { + margin: 0.5em 0; +} +oom-comments .comment-counts { + display: flex; + column-gap: 1em; + font-size: small; +} +oom-comments .comment-counts > span { + display: flex; + align-items: center; + column-gap: 0.3em; + color: gray; +} @@ -1,7 +1,7 @@ --- layout: page title: DN42 -in_navbar: true +in_navbar: false order: 50 lang: "en" --- diff --git a/projects.md b/projects.md new file mode 100644 index 0000000..b3d47f7 --- /dev/null +++ b/projects.md @@ -0,0 +1,31 @@ +--- +layout: page +title: Projects +in_navbar: true +order: 50 +lang: "en" +--- + +Some of my projects and sites: + +- This blog you're reading right now +- [DN42]({% link dn42.md %}) +- [Wiki](https://uvokchee.de/wiki/) +- [Funkwhale](https://fw.uvok.de/) (currently defunc) +- [Personal Matrix and XMPP Server]({% link contact.html %}) +- Running an authoritative DNS server with [PowerDNS](https://www.powerdns.com/powerdns-community) +- Running various VPS (all with Debian, of course) +- Running [OpenWRT](https://openwrt.org/) in my home network (e.g. for tagged VLAN) [2] +- Running [Proxmox](https://www.proxmox.com/en/) (hosting various LXC containers) in my home +- Running an [RIPE ATLAS](https://atlas.ripe.net/docs/) probe - [software](https://github.com/RIPE-NCC/ripe-atlas-software-probe) +- [OpenPGP WKD](https://wiki.gnupg.org/WKD) via DNS + (for shits and giggles - I don't really write mail, and PGP has it's usability problems) +- [Git server](https://git.uvok.de/) + using [gitolite](https://gitolite.com/gitolite/index.html) [1] + and [cgit](https://git.zx2c4.com/cgit/) + +[1] Can really recommend this if you *don't* want a full-blown Git hosting with + "UI" / CI etc. - just the bare-bones git repository hosting. + (Which saves you setting up the bare git repos manually, though). \ +[2] I tried OPNsense in the past, too. But at some point I ran into problems I couldn't fix. + Also, it was virtualized inside Proxmox. Not the optimal solution. diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..a8e359f --- /dev/null +++ b/readme.txt @@ -0,0 +1,3 @@ +URL scheme for piwigo: + +i.php?/upload/2021/06/04/20210604124815-78046f20-sm.jpg |