Something went wrong. Try again.
Fetches each feed in an OPML file and checks for the when it was last updated. Useful for finding discontinued or inactive feeds.
Something went wrong. Try again.
2.1 kB · 72 lines · Created 5mo ago
Shell
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172#!/usr/bin/env bash
OPML_FILE=""DAYS=90
usage() { echo "Usage: $0 -f <opml_file> [-d <days>]" echo "Example: $0 -f subscriptions.opml -d 180" exit 1}
while getopts "f:d:h" opt; do case ${opt} in f ) OPML_FILE=$OPTARG ;; d ) DAYS=$OPTARG ;; h ) usage ;; * ) usage ;; esacdone
if [[ -z "$OPML_FILE" || ! -f "$OPML_FILE" ]]; then echo "Error: Please provide a valid OPML file." usagefi
NOW=$(date +%s)LIMIT_SEC=$((DAYS * 86400))
echo "Analysing feeds in $OPML_FILE (flagging older than $DAYS days)..."echo "------------------------------------------------------------------"
feed_urls=$(tr '><' '\n\n' < "$OPML_FILE" | grep -Eiho 'xmlUrl="[^"]+"' | cut -d'"' -f2)
for url in $feed_urls; do # Fetch feed, handle compression, and extract the first date-like element. # grep -m 1 stops parsing after the first match, terminating the curl download early. date_str=$(curl -sL --compressed --max-time 10 "$url" 2>/dev/null | \ grep -Eio -m 1 '<(pubDate|updated|lastBuildDate|published)>[^<]+|"date_published":"[^"]+|"date_modified":"[^"]+' | \ head -n 1 | \ sed -E 's/<[^>]+>|"date_(published|modified)":"//g' | tr -d '\r\n') if [[ -z "$date_str" ]]; then echo "[UNKNOWN] $url - No parsable date found (or feed is unreachable)." continue fi
feed_ts=""
# Try GNU date if date -d "$date_str" +%s >/dev/null 2>&1; then feed_ts=$(date -d "$date_str" +%s) # Try gdate (macOS if GNU coreutils is installed) elif command -v gdate >/dev/null 2>&1 && gdate -d "$date_str" +%s >/dev/null 2>&1; then feed_ts=$(gdate -d "$date_str" +%s) fi
if [[ -z "$feed_ts" ]]; then echo "[PARSE ERROR] $url - Found date but couldn't parse format: '$date_str'" continue fi
diff=$((NOW - feed_ts)) if (( diff > LIMIT_SEC )); then days_old=$((diff / 86400)) echo "[STALE] $url - $days_old days old (Last updated: $date_str)" fi
done
echo "------------------------------------------------------------------"echo "Finished."