Splux Linux

source-based Linux using SPS

splux-site · log · files · refs · tags · releases · people · languages · GitHub · commit

418381a


Show GitHub profile pictures next to news authors.

Date
Commit418381a5250bb629fd72041e5253a59b0cba846c
GitHubmirror

Parents

Stat

 site/assets/live.js   | 29 ++++++++++++++++++++++++++---
 site/assets/style.css | 12 ++++++++++++
 tools/collect-news.sh | 37 +++++++++++++++++++++++++++----------
 tools/news.awk        | 24 ++++++++++++++++--------
 4 files changed, 81 insertions(+), 21 deletions(-)

Diff

diff --git a/site/assets/live.js b/site/assets/live.js
index df85ab0..7b94072 100644
--- a/site/assets/live.js
+++ b/site/assets/live.js
@@ -117,6 +117,7 @@
 				repo: a.getAttribute("data-repo") || "",
 				author: a.getAttribute("data-author") || "",
 				verified: a.getAttribute("data-verified") === "yes",
+				avatar: a.getAttribute("data-avatar") || "",
 				url: link.getAttribute("href") || "",
 				title: link.textContent || "",
 				summary: summary ? summary.textContent : ""
@@ -139,6 +140,7 @@
 				repo: it.repo || "",
 				author: it.author || "",
 				verified: !!it.verified,
+				avatar: it.avatar || "",
 				url: it.url,
 				title: it.title || "",
 				summary: it.summary || ""
@@ -147,16 +149,35 @@
 		return items;
 	}
 
+	function avatarOf(it) {
+		var av = it && it.avatar ? String(it.avatar) : "";
+		if (/^https:\/\/(avatars\.githubusercontent\.com\/|github\.com\/)/.test(av))
+			return av;
+		var name = it && it.author ? String(it.author) : "";
+		if (/^[A-Za-z0-9-]+$/.test(name))
+			return "https://github.com/" + name + ".png?size=48";
+		return "";
+	}
+
 	function renderItem(it, hideSummary) {
+		var av = avatarOf(it);
 		var html = "<article class=\"item\" data-kind=\"" + esc(it.kind || "") +
 			"\" data-repo=\"" + esc(it.repo || "") +
 			"\" data-author=\"" + esc(it.author || "") +
-			"\" data-verified=\"" + (it.verified ? "yes" : "no") + "\">";
+			"\" data-verified=\"" + (it.verified ? "yes" : "no") +
+			"\" data-avatar=\"" + esc(av) + "\">";
 		html += "<p class=\"meta\"><time datetime=\"" + esc(it.iso) + "\">" +
 			esc(formatLocal(it.iso)) + "</time> <span class=\"kind\">" +
 			esc(it.kind) + "</span> " + esc(it.repo);
-		if (it.author)
-			html += " <span class=\"who\">" + esc(it.author) + "</span>";
+		if (it.author || av) {
+			html += " <span class=\"who\">";
+			if (av)
+				html += "<img class=\"avatar\" src=\"" + esc(av) +
+					"\" width=\"24\" height=\"24\" alt=\"\" loading=\"lazy\">";
+			if (it.author)
+				html += esc(it.author);
+			html += "</span>";
+		}
 		if (it.verified)
 			html += " <span class=\"verified\">verified</span>";
 		html += "</p>";
@@ -324,6 +345,7 @@
 				repo: "SPS",
 				author: (r.author && r.author.login) || "",
 				verified: false,
+				avatar: (r.author && r.author.avatar_url) || "",
 				url: r.html_url || "",
 				title: r.name || r.tag_name || "",
 				summary: body
@@ -350,6 +372,7 @@
 				repo: label,
 				author: author,
 				verified: !!ver.verified,
+				avatar: (c.author && c.author.avatar_url) || "",
 				url: c.html_url || "",
 				title: firstLine(commit.message),
 				summary: ""
diff --git a/site/assets/style.css b/site/assets/style.css
index 6421253..2a76132 100644
--- a/site/assets/style.css
+++ b/site/assets/style.css
@@ -279,9 +279,21 @@ footer p {
 }
 
 .feed .who {
+	display: inline-flex;
+	align-items: center;
+	gap: 0.35rem;
 	color: var(--fg);
 }
 
+.feed .avatar {
+	display: block;
+	width: 24px;
+	height: 24px;
+	border: 1px solid var(--rule);
+	background: #111;
+	flex-shrink: 0;
+}
+
 .feed .verified {
 	display: inline-block;
 	color: var(--accent);
diff --git a/tools/collect-news.sh b/tools/collect-news.sh
index 11ffa3f..7b78130 100755
--- a/tools/collect-news.sh
+++ b/tools/collect-news.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 # Collect Splux releases and git history into TSV for the news page.
-# Fields: epoch iso kind repo url title summary author verified
+# Fields: epoch iso kind repo url title summary author verified avatar
 # Env: CORE EXTRA SPS SITE (git work trees). GH_TOKEN optional via gh.
 # Pulls every non-draft SPS release and every commit available from the
 # local clones and from the GitHub API. Duplicate URLs keep the last row
@@ -29,16 +29,30 @@ emit() {
 	summary=${7-}
 	author=${8-}
 	verified=${9-}
+	avatar=${10-}
 	title=$(printf '%s' "$title" | tr '\t\r\n' '   ')
 	summary=$(printf '%s' "$summary" | tr '\t\r\n' '   ')
 	author=$(printf '%s' "$author" | tr '\t\r\n' '   ')
+	avatar=$(printf '%s' "$avatar" | tr '\t\r\n' '   ')
 	case $verified in
 		yes|no) ;;
 		*) verified= ;;
 	esac
-	printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \
+	case $avatar in
+		https://avatars.githubusercontent.com/*|https://github.com/*.png*) ;;
+		*) avatar=$(github_avatar "$author") ;;
+	esac
+	printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \
 		"$epoch" "$iso" "$kind" "$repo" "$url" "$title" "$summary" \
-		"$author" "$verified" >>"$out"
+		"$author" "$verified" "$avatar" >>"$out"
+}
+
+github_avatar() {
+	login=$1
+	case $login in
+		""|*[!A-Za-z0-9-]*) ;;
+		*) printf 'https://github.com/%s.png?size=48' "$login" ;;
+	esac
 }
 
 epoch_of() {
@@ -67,21 +81,22 @@ git_commits() {
 		[ -n "${iso-}" ] || continue
 		[ -n "${hash-}" ] || continue
 		emit "$epoch" "$iso" commit "$repo" \
-			"$baseurl/commit/$hash" "$subject" "" "$author" ""
+			"$baseurl/commit/$hash" "$subject" "" "$author" "" \
+			"$(github_avatar "$author")"
 	done
 }
 
 read_commit_tsv() {
 	repo=$1
 	file=$2
-	while IFS=$tab read -r published url title author verified || [ -n "${published-}" ]
+	while IFS=$tab read -r published url title author verified avatar || [ -n "${published-}" ]
 	do
 		[ -n "${published-}" ] || continue
 		[ -n "${url-}" ] || continue
 		[ -n "${title-}" ] || title=$url
 		epoch=$(epoch_of "$published")
 		emit "$epoch" "$published" commit "$repo" "$url" "$title" "" \
-			"$author" "$verified"
+			"$author" "$verified" "$avatar"
 	done <"$file"
 }
 
@@ -97,16 +112,17 @@ if command -v gh >/dev/null 2>&1; then
 			.html_url,
 			((.name // .tag_name) | gsub("[\r\t]"; " ")),
 			((.body // "") | gsub("[\r\t]"; " ") | gsub("\n+"; " ") | .[0:900]),
-			((.author.login // "") | gsub("[\r\t]"; " "))
+			((.author.login // "") | gsub("[\r\t]"; " ")),
+			((.author.avatar_url // "") | gsub("[\r\t]"; " "))
 		] | @tsv' >"$tmp/rel"
 	then
-		while IFS=$tab read -r published url name body author || [ -n "${published-}" ]
+		while IFS=$tab read -r published url name body author avatar || [ -n "${published-}" ]
 		do
 			[ -n "${published-}" ] || continue
 			[ -n "${url-}" ] || continue
 			epoch=$(epoch_of "$published")
 			emit "$epoch" "$published" release SPS "$url" "$name" "$body" \
-				"$author" ""
+				"$author" "" "$avatar"
 		done <"$tmp/rel"
 	else
 		printf '%s\n' "collect-news: GitHub releases request failed" >&2
@@ -121,7 +137,8 @@ if command -v gh >/dev/null 2>&1; then
 				.html_url,
 				((.commit.message // "") | split("\n")[0] | gsub("[\r\t]"; " ")),
 				((.author.login // .commit.author.name // "") | gsub("[\r\t]"; " ")),
-				(if .commit.verification.verified == true then "yes" else "no" end)
+				(if .commit.verification.verified == true then "yes" else "no" end),
+				((.author.avatar_url // "") | gsub("[\r\t]"; " "))
 			] | @tsv' >"$tmp/c"
 		then
 			read_commit_tsv "$label" "$tmp/c"
diff --git a/tools/news.awk b/tools/news.awk
index af2d0c1..75c3a05 100644
--- a/tools/news.awk
+++ b/tools/news.awk
@@ -1,5 +1,5 @@
 # Turn collect-news.sh TSV into HTML, a pager, JSON, or Atom.
-# Fields: epoch iso kind repo url title summary author verified
+# Fields: epoch iso kind repo url title summary author verified avatar
 # -v mode=html|brief|atom|json|pager
 # -v page= -v per= -v pages= -v nest=0|1  -v siteurl=  -v feedupdated=
 
@@ -73,6 +73,7 @@ function page_href(p) {
 	summary[n] = $7
 	author[n] = $8
 	verified[n] = $9
+	avatar[n] = $10
 }
 
 END {
@@ -112,17 +113,24 @@ END {
 	print "</div>"
 }
 
-function print_item(i, brief,    k, when, s, v, a) {
+function print_item(i, brief,    k, when, s, v, a, av) {
 	when = esc(utc_label(iso[i]))
 	k = esc(kind_label(kind[i]))
 	a = author[i]
 	v = verified[i]
-	printf "<article class=\"item\" data-kind=\"%s\" data-repo=\"%s\" data-author=\"%s\" data-verified=\"%s\">\n", \
-		k, esc(repo[i]), esc(a), esc(v)
+	av = avatar[i]
+	printf "<article class=\"item\" data-kind=\"%s\" data-repo=\"%s\" data-author=\"%s\" data-verified=\"%s\" data-avatar=\"%s\">\n", \
+		k, esc(repo[i]), esc(a), esc(v), esc(av)
 	printf "<p class=\"meta\"><time datetime=\"%s\">%s</time> <span class=\"kind\">%s</span> %s", \
 		esc(iso[i]), when, k, esc(repo[i])
-	if (a != "")
-		printf " <span class=\"who\">%s</span>", esc(a)
+	if (a != "" || av != "") {
+		printf " <span class=\"who\">"
+		if (av != "")
+			printf "<img class=\"avatar\" src=\"%s\" width=\"24\" height=\"24\" alt=\"\" loading=\"lazy\">", esc(av)
+		if (a != "")
+			printf "%s", esc(a)
+		printf "</span>"
+	}
 	if (v == "yes")
 		printf " <span class=\"verified\">verified</span>"
 	print "</p>"
@@ -200,10 +208,10 @@ function print_json(    i, v) {
 		if (i > 1)
 			print ","
 		v = (verified[i] == "yes") ? "true" : "false"
-		printf "{\"iso\":\"%s\",\"kind\":\"%s\",\"repo\":\"%s\",\"url\":\"%s\",\"title\":\"%s\",\"summary\":\"%s\",\"author\":\"%s\",\"verified\":%s}", \
+		printf "{\"iso\":\"%s\",\"kind\":\"%s\",\"repo\":\"%s\",\"url\":\"%s\",\"title\":\"%s\",\"summary\":\"%s\",\"author\":\"%s\",\"verified\":%s,\"avatar\":\"%s\"}", \
 			jesc(iso[i]), jesc(kind_label(kind[i])), jesc(repo[i]), \
 			jesc(url[i]), jesc(title[i]), jesc(summary[i]), \
-			jesc(author[i]), v
+			jesc(author[i]), v, jesc(avatar[i])
 	}
 	print "\n]"
 }