#!/bin/bash # Header if [[ $MF_DEBUG -eq 1 ]]; then printf "miniflux-filter - git.mgrote.net/mg/miniflux-filter\n" fi ### wartezeit zwischen laeufen MF_SLEEP="${MF_SLEEP:=30}" ### MF_DEBUG output # standardmäßig 0 = aus MF_DEBUG="${MF_DEBUG=0}" # Functions function output_help { cat < /dev/null then echo "[ERROR] jq could not be found!" exit 5 fi if ! command -v curl &> /dev/null then echo "[ERROR] curl could not be found!" exit 6 fi if ! command -v xargs &> /dev/null then echo "[ERROR] xargs could not be found!" exit 8 fi if ! command -v sed &> /dev/null then echo "[ERROR] sed could not be found!" exit 9 fi if ! command -v sort &> /dev/null then echo "[ERROR] sort could not be found!" exit 10 fi if ! command -v awk &> /dev/null then echo "[ERROR] awk could not be found!" exit 11 fi } function check_vars { if [[ $MF_DEBUG -eq 1 ]]; then echo "[DEBUG] check if vars are (correctly) set" fi # pruefe ob alle vars gesetzt sind # -z = ob laenge gleich null ist if [[ -z "${MF_AUTH_TOKEN}" ]]; then # shellcheck disable=SC2016 # shellcheck disable=SC2102 echo [ERROR] '"$MF_AUTH_TOKEN"' not set. exit 2 fi if [[ -z "${MF_API_URL}" ]]; then # shellcheck disable=SC2016 # shellcheck disable=SC2102 echo [ERROR] '"$MF_API_URL"' not set. exit 3 fi # pruefe ob filter-datei NICHT existiert if [[ -z "${MF_FILTERLIST}" ]]; then # shellcheck disable=SC2016 # shellcheck disable=SC2102 echo [ERROR] '"$MF_FILTERLIST"' not set. exit 1 fi } function check_ping_connectivity { if [[ $MF_DEBUG -eq 1 ]]; then echo "[DEBUG] check if miniflux can be reached with ping" fi # pruefe ob miniflux erreichbar ist, wenn ja setze abbruchbedingung, sonst warte mf_ping_connectivity=0 while [[ $mf_ping_connectivity -eq 0 ]]; do # hole fqdn + port aus MF_API_URL und pinge an mf_fqdn=$(echo "$MF_API_URL" | cut -d'/' -f3 | cut -d':' -f1-2 | cut -d":" -f1) if ping -c 1 "$mf_fqdn" > /dev/null 2>&1 ; then mf_ping_connectivity=1 else mf_ping_connectivity=0 sleep 10 echo "[INFO] wait for miniflux (ping)..." if [[ $MF_DEBUG -eq 1 ]]; then echo "[DEBUG] miniflux could not be pinged, wait 10s" fi fi done } function check_api_connectivity { if [[ $MF_DEBUG -eq 1 ]]; then echo "[DEBUG] check if miniflux-api can be reached with curl" fi # pruefe ob miniflux erreichbar ist, wenn ja setze abbruchbedingung, sonst warte mf_api_connectivity=0 while [[ $mf_api_connectivity -eq 0 ]]; do http_status_code=$(curl --silent --header "X-Auth-Token: $MF_AUTH_TOKEN" "$MF_API_URL/me" -i | grep HTTP/2 | awk '{print $2}') if [[ $http_status_code -eq 200 ]] ; then mf_api_connectivity=1 else mf_api_connectivity=0 sleep 10 echo "[INFO] wait for miniflux (api)..." if [[ $MF_DEBUG -eq 1 ]]; then echo "[DEBUG] api could not be reached, wait 10s" fi fi done } function debug_output { if [[ $MF_DEBUG -eq 1 ]]; then echo ----------------------------------------------------- echo [DEBUG] Sleep-Intervall: "$MF_SLEEP" echo [DEBUG] Auth-Token: "$MF_AUTH_TOKEN" echo [DEBUG] MF-URL: "$MF_API_URL" echo ----------------------------------------------------- fi } function get_unread_entries { # hole alle ungelesenen entries und speichere sie in der variable unread_entries if [[ $MF_DEBUG -eq 1 ]]; then echo "[DEBUG] get unread entries from miniflux" fi unread_entries="$(curl --silent --header "X-Auth-Token: $MF_AUTH_TOKEN" "$MF_API_URL/entries?status=unread&limit=0")" if [[ $MF_DEBUG -eq 1 ]]; then echo "[DEBUG] show unread entries from miniflux" echo ----------------------------------------------------- echo "$unread_entries" echo ----------------------------------------------------- fi } function filter_entries { echo "[INFO] Filtering entries..." # fuer jede Zeile in $MF_FILTERLIST echo "$MF_FILTERLIST" | while read -r line; do if [[ $MF_DEBUG -eq 1 ]]; then echo "[DEBUG] set search values" fi # setze $url auf den Wert vor dem Trennzeichen/Delimiter, ersetze alle Grossschreibungen durch Kleinschreibung url=$(echo "$line" | tr '[:upper:]' '[:lower:]' | awk --field-separator="::" '{print $1}') # setze $suchbegriff auf den Wert vor dem Trennzeichen/Delimiter, ersetze alle Grossschreibungen durch Kleinschreibung suchbegriff=$(echo "$line" | tr '[:upper:]' '[:lower:]' | awk --field-separator="::" '{print $2}') # in jq uebergebe shell-variablen an jq selber # entferne die erste ebene # suche jeden eintrag wo die feed_url == $url, konvertiere in kleinschreibung, dasselbe fuer den title # gebe dann nur die id aus # die id, wird dann an die variable marked_entries angehangen # z.B. 53443 52332 48787 [...] if [[ -n "$url" ]]; then # abfangen der letzten zeile die leer ist; sonst wird alles gefiltert if [[ -n "$suchbegriff" ]]; then # abfangen der letzten zeile die leer ist; sonst wird alles gefiltert if [[ $MF_DEBUG -eq 1 ]]; then echo [DEBUG] url:"$url" - value:"$suchbegriff" fi # das leerzeichen am anfang ist notwendig, trennt die zahlenwerte # suche in titel marked_entries+=" $(echo "$unread_entries" | jq --arg url "$url" --arg suchbegriff "$suchbegriff" '.entries[] | select(.feed.site_url | ascii_downcase | contains($url)) | select(.title | ascii_downcase | contains($suchbegriff)) | .id' )" # suche in content marked_entries+=" $(echo "$unread_entries" | jq --arg url "$url" --arg suchbegriff "$suchbegriff" '.entries[] | select(.feed.site_url | ascii_downcase | contains($url)) | select(.content | ascii_downcase | contains($suchbegriff)) | .id' )" fi fi # sortiere und forme marked_entries um # https://unix.stackexchange.com/questions/353321/remove-all-duplicate-word-from-string-using-shell-script # entfernt doppelte eintraege innerhalb einer zeile marked_entries=$(echo marked_entries | xargs -n1 | sort -u | xargs | sed -r 's/\s/\, /g') echo $marked_entries done } function mark_as_read { # https://stackoverflow.com/questions/3869072/test-for-non-zero-length-string-in-bash-n-var-or-var # wenn variable NICHT leer... # sende in put request mit curl # der wert muss escaped werden, aber NICHT die variable die uebergeben wird if [[ $MF_DEBUG -eq 1 ]]; then echo "[DEBUG] mark entries as read" echo "[DEBUG] marked entry ids: $marked_entries" echo "$marked_entries" fi # wenn NICHT leer # sed wandelt 123 345 456 in 123, 245, 345 um. if [[ -n "$marked_entries" ]]; then curl --request PUT --silent --header "X-Auth-Token: $MF_AUTH_TOKEN" --header "Content-Type: application/json" --data "{\"entry_ids\": [$(echo "$marked_entries" | xargs -n1 | sort -u | xargs | sed -r 's/\s/\, /g')], \"status\": \"read\"}" "$MF_API_URL/entries" # gebe entry-titel aus for i in $(echo "$marked_entries" | xargs -n1 | sort -u | xargs); do # gebe aus welcher eintrag gefiltert wurde, cut begrenzt die maximale laenge auf 100 zeichen # jq "XXX", fügt XXX in ausgabe hinzu echo [INFO] Filtered entry "$i" - "$(curl --silent --header "X-Auth-Token: $MF_AUTH_TOKEN" "$MF_API_URL"/entries/"$i" | jq --join-output '"url: ",.feed.site_url," - title: ", .title' | cut -c -100)". done fi # setze variablen auf leer marked_entries="" } # debug MF_FILTERLIST=" facebook.com::Bridge returned error golem.de::Anzeige golem.de::Aus dem Verlag: golem.de::Elon Musk golem.de::Fifa golem.de::Fussball golem.de::Fußball golem.de::(g+) golem.de::Golem Karrierewelt www.thedrive.com::Bunker Talk: golem.de::in aller Kürze golem.de::In eigener Sache golem.de::kurznews golem.de::Marvel golem.de::Podcast golem.de::PODCAST BESSER WISSEN: golem.de::Sonst noch was? golem.de::Star Trek: golem.de::Tech Talks: golem.de::Twitter golem.de::Wochenrückblick hardwareluxx.de::Der Hardwareluxx-Webwatch: hardwareluxx.de::Die Artikel unserer Partner hardwareluxx.de::Shopping Club hardwareluxx.de::KW heise.de::Anzeige heise.de::Auslegungssache heise.de::Bit-Rauschen heise.de::Bit-Rauschen, der Prozessor-Podcast heise.de::c't heise.de::c’t-Webinar: heise.de::Desinfec heise.de::Die Bilder der Woche (KW heise.de::Die Highlights bei heise.de::Dienstag heise.de::Dienstag: heise.de::Die Produktwerker heise.de::Elon Musk heise.de::Ferris Talk heise.de::FIFA heise.de::Freitag heise.de::Fußball-WM heise.de::heise+ " # Doing case "$1" in --help | -h | help) output_help ;; *) check_dependencies # fuehre script durchgaengig aus while true; do check_vars debug_output check_ping_connectivity check_api_connectivity get_unread_entries filter_entries mark_as_read # warte zeit x sleep "$MF_SLEEP" done esac # curl --request PUT --header "X-Auth-Token: hLPp23gO8QeZWPYXXXXXXXMs0jG0XTYgNZBgRA=" --header "Content-Type: application/json" --data '{"entry_ids":[388229, 388211], "status":"read"}' https://miniflux.mgrote.net/v1/entries