rss.sh (2900B)
1 #!/bin/sh 2 3 env="${1:-./.env}" 4 # shellcheck source=./.env.template 5 . "$env" 6 7 exclude_files="${exclude_files}" 8 meta_ext="${meta_ext:-.meta}" 9 site_root="${site_root}" 10 html_dir="${html_dir:-html}" 11 post_dir="${post_dir:-posts}" 12 13 rss_root="${rss_root}" 14 rss_title="${rss_title}" 15 rss_description="${rss_description}" 16 rss_link="${rss_link}" 17 18 log() { 19 printf 'shite: [%s] %s\n' "$1" "$2" >&2 20 } 21 info() { 22 log "$(printf '\033[32minfo\033[0m')" "$1" 23 } 24 warn() { 25 log "$(printf '\033[33mwarn\033[0m')" "$1" 26 } 27 error() { 28 log "$(printf '\033[31merror\033[0m')" "$1" 29 } 30 die() { 31 error "$1" 32 printf 'exiting...\n' >&2 33 exit 1 34 } 35 36 # convert input date to RFC2822 37 # time and tz are set to 00:00:00 +0000 38 # $1 - input date 39 to_rfc2822() { 40 date="$1" 41 format="%F" 42 rfc2822="+%a, %d %b %Y 00:00:00 +0000" 43 44 # if on Linux, use GNU date syntax 45 if [ "$(uname)" = "Linux" ]; then 46 date -d "$date" "$rfc2822" 47 else 48 date -j -f "$format" "$date" "$rfc2822" 49 fi 50 } 51 52 rss_preamble() { 53 printf '<rss version="2.0" xml:base="%s">\n' "$rss_root" 54 printf '<channel>\n' 55 printf '<title>%s</title>\n' "$rss_title" 56 if [ -n "$rss_description" ]; then 57 printf '<description>\n' 58 printf '%s\n' "$rss_description" 59 printf '</description>\n' 60 else 61 printf '<description/>\n' 62 fi 63 printf '<link>%s</link>\n' "$rss_link" 64 } 65 66 rss_postamble() { 67 printf '</channel>\n' 68 printf '</rss>\n' 69 } 70 71 gen_rss() { 72 find "${site_root}/${post_dir}/" -name '*.md' | while read -r post; do 73 post_html="${post%.*}.html" 74 post_meta="${post%.*}${meta_ext}" 75 post_url="/posts/$(basename "$post_html")" 76 77 excluded=0 78 for ex in $exclude_files; do 79 if [ "$(basename "$post")" = "$ex" ]; then 80 excluded=1 81 fi 82 done 83 84 if [ "$excluded" -eq 1 ]; then 85 warn "${post} excluded" 86 continue 87 fi 88 89 # parse metadata if .meta file exists 90 if [ -f "$post_meta" ]; then 91 # read the 'key: value' .meta file 92 while IFS=': ' read -r key val; do 93 [ "${key##\#*}" ] || continue 94 # export each key as a variable; '$post_<key>' 95 export "post_${key}=${val}" 2>/dev/null || \ 96 warn "'${key}' is not a valid meta tag name" 97 done < "$post_meta" 98 else 99 warn "no ${meta_ext} - skipping metadata parsing" 100 fi 101 102 echo "${post_date}|${post_title}|${post_url}|${post}" >> rss.meta 103 104 unset post_date 105 unset post_title 106 unset post_image 107 unset post_description 108 unset post_url 109 done 110 111 rss_preamble 112 sort -r rss.meta | while IFS='|' read -r post_date post_title post_url post_md; do 113 [ -z "$post_date" ] && continue 114 rfcdate="$(to_rfc2822 "$post_date")" 115 printf '<item>\n' 116 printf '<link>%s%s</link>\n' "$rss_root" "$post_url" 117 printf '<title>%s</title>\n' "$post_title" 118 printf '<pubDate>%s</pubDate>\n' "$rfcdate" 119 printf '<description>\n' 120 lowdown -Thtml < "$post_md" 121 printf '</description>\n' 122 printf '</item>\n' 123 done 124 rss_postamble 125 } 126 127 gen_rss 128 rm -i rss.meta