#!/usr/bin/env bash OPML_FILE="" DAYS=90 usage() { echo "Usage: $0 -f [-d ]" 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 ;; esac done if [[ -z "$OPML_FILE" || ! -f "$OPML_FILE" ]]; then echo "Error: Please provide a valid OPML file." usage fi 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."