#!/bin/awk -f # Convert sfeed(1) formatted files into an HTML webpage. # Usage: sfeed_html.awk -- FILES... ## Set up variables BEGIN { # Sidebar if (! ASIDE) { ASIDE = envor("SFEED_HTML_ASIDE", "/tmp/sfeed-aside.html") } print > ASIDE # clear out ASIDE in_aside = 0 # Don't show the feed in the sidebar # Formatting if (! DATEFMT) { ddf = "" DATEFMT = envor("SFEED_HTML_DATEFMT", ddf) } if (! TITLE) { TITLE = envor("SFEED_HTML_TITLE", "Planet ACDW") } if (! SEPARATOR) { SEPARATOR = envor("SFEED_HTML_SEPARATOR", "//") } if (! ALT_LINK_STAMP) { ALT_LINK_STAMP = envor("SFEED_ALT_LINK_STAMP", "&") } if (! ENCLOSURE_STAMP) { ENCLOSURE_STAMP = envor("SFEED_ENCLOSURE_STAMP", "@") } if (! SILO_STAMP) { SILO_STAMP = envor("SFEED_SILO_STAMP", "%") } # Limiting posts... ## by time if (! NOW) { datecmd = "date +%s" datecmd | getline NOW close(datecmd) } if (! FRESHDAYS) { FRESHDAYS = envor("SFEED_FRESHDAYS", 1.5) } if (! STALEDAYS) { STALEDAYS = envor("SFEED_STALEDAYS", 4) } fresh_secs = FRESHDAYS * 24 * 60 * 60 stale_secs = STALEDAYS * 24 * 60 * 60 fresh_age = (NOW - fresh_secs) stale_age = (NOW - stale_secs) ## by number if (! LIMIT) { # If LIMIT == -1, ignore time limit as well. LIMIT = envor("SFEED_LIMIT", 20) } # Alternate URLs for siloed content if (! YOUTUBE_ALT_URL) { YOUTUBE_ALT_URL = envor("SFEED_YOUTUBE_ALT_URL", "https://piped.kavin.rocks") } if (! TWITTER_ALT_URL) { TWITTER_ALT_URL = envor("SFEED_TWITTER_ALT_URL", "https://nitter.net") } if (! REDDIT_ALT_URL) { REDDIT_ALT_URL = envor("SFEED_REDDIT_ALT_URL", "https://libreddit.de") } if (! MEDIUM_ALT_URL) { MEDIUM_ALT_URL = envor("SFEED_MEDIUM_ALT_URL", "https://scribe.rip") } # Paywalls PAYWALL_LADDER = "https://archive.ph/newest/" PAYWALLED[1] = "washingtonpost\\.com" PAYWALLED[2] = "nytimes\\.com" # Awk and convenience constants FS = "\t" STDERR = "/dev/stderr" } BEGIN { html_top() } FNR == 1 { if (file_count) { # End the previous file before beginning the current one end_file() } # Filename name = FILENAME sub(/.*\//, "", name) safe_name = name sub(/\//, "_", safe_name) dir = FILENAME sub(/[^\/]*$/, "", dir) if (name ~ /\[yt\]$/) { sub(/ \[yt\]$/, "", name) yt = " class=\"yt\"" } else { yt = "" } # extra metadata, yaaaaay feed_url = "" site_url = "" URLS = envor("SFEED_DATA", ENVIRON["HOME"] "/.sfeed") "/urls/" safe_name getline feed_url < URLS getline site_url < URLS getline feed_tags < URLS # put more lines to read here close(URLS) # State variables stamp = "." buf = "" ni = 0 stale_total += stale_count stale_count = 0 fresh_total += fresh_count fresh_count = 0 item_total += item_count item_count = 0 file_count++ siloed = 0 } { # Skip if we have too many items if ((LIMIT > 0) && (++ni > LIMIT)) { next } # Collect fields timestamp = $1 title = $2 silo = $3 link = silo_link(silo) content = unescape($4) content_type = $5 id = $6 author = $7 enclosure = $8 category = $9 # Skip if the item is too old if ((LIMIT >= 0) && (timestamp < stale_age)) { next } # Otherwise, we're showing it stale_count++ # Is this item fresh? if (timestamp >= fresh_age) { is_fresh = 1 stamp = "!" fresh_count++ } else { is_fresh = 0 } # Debugging comment # bufprint("") # bufprint("") # Print! bufprint("") # Timestamp datecmd = "date -d \"@" timestamp "\" +'" DATEFMT "'" if (timestamp) { datecmd | getline timestamp close(datecmd) } bufprint("") # Extra links bufprint("") if (siloed) { # "siloed" links like youtube, facebook, etc. --- I convert them # to more privacy-friendly links, but sometimes those don't # work. TODO: also try to circumvent paywalls. stamp = SILO_STAMP print_link(silo, "Silo: " silo, stamp) } if (enclosure) { # enclosures --- podcast files, etc. stamp = ENCLOSURE_STAMP print_link(enclosure, "Enclosure: " enclosure, stamp) } # Test id against silo here, since silo is the raw link value. if ((id != silo) && (id != enclosure) && (id ~ /^https?:/)) { # alternate links (comments, etc.) stamp = ALT_LINK_STAMP print_link(silo_link(id), "alternate link", stamp) } bufprint("") # Title bufprint("") # bufprint("
", 0) print_link(link, "", title) # bufprint("") # bufprint(content) # bufprint("
") bufprint("") # End row bufprint("") item_count++ } END { # End the last file and the #list section end_file() print "" # Sidebar print "" # End of
print "
" # footer printf "" # end of HTML print "" print "" print "" printf(SEPARATOR) > STDERR } function bufprint(text, sep) { buf = buf text (sep ? sep : ((sep == 0) ? "" : "\n")) sep = "" } function end_file() { if (! item_count) { return 1 } # Header printf "
\n", name, (fresh_count ? "fresh" : "stale") printf "
# %s\n", yt, name, name # Feed links printf "" printf "
\n" # Feed entries printf "\n" printf "%s", buf printf "
\n
\n" # Sidebar if (stale_count) { printf("
  • ", (fresh_count ? "fresh" : "stale")) >> ASIDE printf("%s
  • \n", name, (yt ? " class=\"yt\"" : ""), name) >> ASIDE } # Log printf("%s", stamp) > STDERR } function envor(var, def) { return (ENVIRON[var] ? ENVIRON[var] : def) } function html_escape(t) { gsub(//, "\\>", t) gsub(/&/, "\\&", t) return t } function html_top() { # Print HTML header fortunecmd = "fortune" fortunecmd | getline LOGO_TITLE close(fortunecmd) sub(/"/, "", LOGO_TITLE) datecmd = "date -u +'" DATEFMT "'" datecmd | getline UPDATE_TIME close(datecmd) print "" print "" # print "" print "" print "" print "" print "" print "" TITLE "" print "" print "" print "" print "" print "" print "" print "" print "" print "" #
    print "
    " print "

    " printf "" print TITLE "

    " print "

    last updated at

    " print "
    " #