Created
April 3, 2026 03:45
-
-
Save brandonpollack23/db78386cb84389772974edeb9e9e29bc to your computer and use it in GitHub Desktop.
Hacker news motd script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Hacker News MOTD | |
| _hn_output=$(source "$HOME/rcfiles/hacker-news.sh") | |
| if [[ -n "$_hn_output" ]]; then | |
| echo "$_hn_output" | |
| else | |
| echo "⏳ Fetching Hacker News in the background..." | |
| fi | |
| unset _hn_output |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| _hn_cache="$HOME/.cache/hn_motd" | |
| _hn_default_max_age=${HN_MAX_AGE:-18000} # 5 hours, overridable via env | |
| _hn_default_count=${HN_COUNT:-30} # top N stories to cache, overridable via env | |
| _hn_stale() { | |
| local max_age=${1:-$_hn_default_max_age} | |
| [[ ! -f "$_hn_cache" ]] && return 0 | |
| local age=$(($(date +%s) - $(date -r "$_hn_cache" +%s))) | |
| ((age > max_age)) | |
| } | |
| _hn_fetch() { | |
| local count=${1:-$_hn_default_count} | |
| local ids id item title url text kid comment obj tmpfile | |
| ids=$(curl -sf https://hacker-news.firebaseio.com/v0/topstories.json) || return | |
| tmpfile=$(mktemp) | |
| echo "[]" >"$tmpfile" | |
| for id in $(echo "$ids" | jq ".[: ${count}][]"); do | |
| item=$(curl -sf "https://hacker-news.firebaseio.com/v0/item/${id}.json") || continue | |
| title=$(echo "$item" | jq -r '.title // empty') | |
| [[ -z "$title" ]] && continue | |
| url=$(echo "$item" | jq -r '.url // empty') | |
| text=$(echo "$item" | jq -r '.text // empty') | |
| comment="" | |
| if [[ -n "$url" ]]; then | |
| kid=$(echo "$item" | jq '.kids[0] // empty') | |
| if [[ -n "$kid" ]]; then | |
| comment=$(curl -sf "https://hacker-news.firebaseio.com/v0/item/${kid}.json" | | |
| jq -r '.text // empty' | sed 's/<[^>]*>//g') | |
| comment="${comment:0:100}" | |
| fi | |
| elif [[ -n "$text" ]]; then | |
| comment=$(echo "$text" | sed 's/<[^>]*>//g' | head -c 100) | |
| url="" | |
| fi | |
| obj=$(jq -n --arg t "$title" --arg u "$url" --arg c "$comment" \ | |
| '{title: $t, url: $u, comment: $c}') | |
| jq --argjson e "$obj" '. + [$e]' "$tmpfile" >"${tmpfile}.tmp" && | |
| command mv "${tmpfile}.tmp" "$tmpfile" | |
| done | |
| command mv "$tmpfile" "$_hn_cache" | |
| } | |
| hn() { | |
| local max_age=$_hn_default_max_age count=$_hn_default_count | |
| while [[ $# -gt 0 ]]; do | |
| case $1 in | |
| --max-age) | |
| max_age=$2 | |
| shift 2 | |
| ;; | |
| --count) | |
| count=$2 | |
| shift 2 | |
| ;; | |
| *) shift ;; | |
| esac | |
| done | |
| if [[ ! -f "$_hn_cache" ]]; then | |
| (_hn_fetch "$count" &) | |
| return | |
| elif _hn_stale "$max_age"; then | |
| (_hn_fetch "$count" &) | |
| fi | |
| [[ -f "$_hn_cache" ]] || return | |
| local entry title url comment | |
| entry=$(jq -c '.[]' "$_hn_cache" | shuf -n1) | |
| title=$(echo "$entry" | jq -r '.title') | |
| url=$(echo "$entry" | jq -r '.url') | |
| comment=$(echo "$entry" | jq -r '.comment') | |
| echo -e "\n🔥 \e[2mHacker News MOTD\e[22m\n" | |
| echo -e "📰 \e[1m${title}\e[0m" | |
| [[ -n "$url" ]] && echo -e " ${url}" | |
| [[ -n "$comment" ]] && echo -e " 💬 \e[3m${comment}\e[23m…" | |
| echo | |
| } | |
| hn "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment