From 650c0bf95cb0e21f38fd0c2ddacf8cc9fe5d5f42 Mon Sep 17 00:00:00 2001 From: Stephan Geisler Date: Sun, 12 Jul 2020 18:42:23 +0000 Subject: [PATCH] =?UTF-8?q?=E2=80=9Echangedetection.sh=E2=80=9C=20=C3=A4nd?= =?UTF-8?q?ern?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- changedetection.sh | 335 +++++++++++++++++++++++++-------------------- 1 file changed, 188 insertions(+), 147 deletions(-) diff --git a/changedetection.sh b/changedetection.sh index 85f18d6..46cc3a5 100644 --- a/changedetection.sh +++ b/changedetection.sh @@ -1,7 +1,8 @@ #!/bin/sh # changedetection # v1.2@geimist -# 2020-07-11 +# 2020-07-12 +# /volume1/homes/admin/script/changedetection/changedetection.sh # Definition der Variablen: EMPFAENGER=user@domain.de @@ -32,176 +33,217 @@ purge_LOG() ######################################################################################### # This function cleans up older log files # ######################################################################################### +echo -e if [ -z $MAXDAY ]; then echo "purge_LOG deactivated" return fi anzahl=0 -for del in $(find "${APPDIR}/change_detected/" -mtime +$MAXDAY -maxdepth 1 -type f); do +# -maxdepth 1 +for del in $(find "${APPDIR}/change_detected/" -type f -mtime +${MAXDAY}); do anzahl=$( expr $anzahl + 1 ) rm -f "$del" done -echo " Logfiles gelöscht: $anzahl" +printf "%-${1}s%s\n" "➜ Logfiles gelöscht: " "$anzahl" } + +sec_to_time() +{ +# this function converts a second value to hh:mm:ss +# call: sec_to_time "string" +# https://blog.jkip.de/in-bash-sekunden-umrechnen-in-stunden-minuten-und-sekunden/ +# -------------------------------------------------------------- + local seconds=$1 + local sign="" + if [[ ${seconds:0:1} == "-" ]]; then + seconds=${seconds:1} + sign="-" + fi + local hours=$(( seconds / 3600 )) + local minutes=$(( (seconds % 3600) / 60 )) + seconds=$(( seconds % 60 )) + printf "%s%02d:%02d:%02d" "$sign" $hours $minutes $seconds +} + + +# berechne Zeichenlänge für Log: +NAMElen=0 +while read i ; do + if [ "$i" == "" ]; then + continue + elif echo "$i" | grep -q '^#'; then # auskommentierte Zeilen überspringen + continue + fi + + ilen=$(echo $i | awk -F ' "' '{print $1}' | sed 's/\"//g ; s/\ $//g' | wc -c ) + if [ $ilen -gt $NAMElen ] ;then + NAMElen=$ilen + fi +done < "${APPDIR}/SITES.txt" + +NAMElen=$((NAMElen + 5)) + + +# Quelle zeilenweise einlesen: +while read i ; do + date_start=$(date +%s) -while read i # Quelle zeilenweise einlesen - do - if [ "$i" == "" ]; then - continue - elif echo "$i" | grep -q '^#'; then # auskommentierte Zeilen überspringen - continue - fi + if [ "$i" == "" ]; then + continue + elif echo "$i" | grep -q '^#'; then # auskommentierte Zeilen überspringen + continue + fi - NAME=$(echo $i | awk -F ' "' '{print $1}' | sed 's/\"//g ; s/\ $//g') - LINK=$(echo $i | awk -F ' "' '{print $2}' | sed 's/\"//g') - CutStart=$(echo $i | awk -F ' "' '{print $3}' | sed 's/\"//g') - CutEnd=$(echo $i | awk -F ' "' '{print $4}' | sed 's/\"//g') - PushInfo=$(echo $i | awk -F ' "' '{print $5}' | sed 's/\"//g') - - echo -e; echo -n "=> ${NAME}: " - - # 1.: lade aktuelle index.html - #--------------------------------------------- - # vorherige Datei sichern: - if [ -f "${APPDIR}/tmp/${NAME}.txt" ] ; then - mv "${APPDIR}/tmp/${NAME}.txt" "${APPDIR}/tmp/${NAME}_old.txt" - fi - - machinetyp=$(uname --machine) - # links = SPK von synocommunity https://synocommunity.com/package/links - # manual: https://www.mankier.com/1/links2 - # Parameter "ssl.certificates 0" in Datei ~/.links/links.cfg notwendig oder direkt übergeben (warum können Certs nicht validiert werden?) - if [ $machinetyp = "x86_64" ]; then - ${APPDIR}/links_APP/bin/links -dump "$LINK" -memory-cache-size 1 -ssl.certificates 0 -codepage "utf-8" -http.fake-firefox 1 -anonymous > "${APPDIR}/tmp/${NAME}.txt" - else - links -dump "$LINK" -memory-cache-size 1 -ssl.certificates 0 -codepage "utf-8" -http.fake-firefox 1 -anonymous > "${APPDIR}/tmp/${NAME}.txt" - fi - # Überhänge löschen - if [ -n "$CutStart" ]; then # alles vorm Start-Keyword löschen - CutStartRow=$(cat "${APPDIR}/tmp/${NAME}.txt" | egrep -n "$CutStart" | cut -d":" -f1 | head -n1) - sed -i "1,${CutStartRow}d" "${APPDIR}/tmp/${NAME}.txt" #> "${APPDIR}/tmp/${NAME}_tmp.txt" - fi + NAME=$(echo $i | awk -F ' "' '{print $1}' | sed 's/\"//g ; s/\ $//g') + LINK=$(echo $i | awk -F ' "' '{print $2}' | sed 's/\"//g') + CutStart=$(echo $i | awk -F ' "' '{print $3}' | sed 's/\"//g') + CutEnd=$(echo $i | awk -F ' "' '{print $4}' | sed 's/\"//g') + PushInfo=$(echo $i | awk -F ' "' '{print $5}' | sed 's/\"//g') + + echo -e; #echo -n "=> ${NAME}: " + +# 1.: lade aktuelle index.html +#--------------------------------------------- + # vorherige Datei sichern: + if [ -f "${APPDIR}/tmp/${NAME}.txt" ] ; then + mv "${APPDIR}/tmp/${NAME}.txt" "${APPDIR}/tmp/${NAME}_old.txt" + fi + + machinetyp=$(uname --machine) + # links = SPK von synocommunity https://synocommunity.com/package/links + # manual: https://www.mankier.com/1/links2 + # Parameter "ssl.certificates 0" in Datei ~/.links/links.cfg notwendig oder direkt übergeben (warum können Certs nicht validiert werden?) + if [ $machinetyp = "x86_64" ]; then + ${APPDIR}/links_APP/bin/links -dump "$LINK" -memory-cache-size 1 -ssl.certificates 0 -codepage "utf-8" -http.fake-firefox 1 -anonymous > "${APPDIR}/tmp/${NAME}.txt" + else + links -dump "$LINK" -memory-cache-size 1 -ssl.certificates 0 -codepage "utf-8" -http.fake-firefox 1 -anonymous > "${APPDIR}/tmp/${NAME}.txt" + fi +# Überhänge löschen + if [ -n "$CutStart" ]; then # alles vorm Start-Keyword löschen + CutStartRow=$(cat "${APPDIR}/tmp/${NAME}.txt" | egrep -n "$CutStart" | cut -d":" -f1 | head -n1) + sed -i "1,${CutStartRow}d" "${APPDIR}/tmp/${NAME}.txt" #> "${APPDIR}/tmp/${NAME}_tmp.txt" + fi - if [ -n "$CutEnd" ]; then # alles nach dem End-Keyword löschen - CutEndRow=$(cat "${APPDIR}/tmp/${NAME}.txt" | egrep -n "$CutEnd" | cut -d":" -f1 | head -n1) - LineCount=$(cat "${APPDIR}/tmp/${NAME}.txt" | wc -l ) - sed -i "${CutEndRow},${LineCount}d" "${APPDIR}/tmp/${NAME}.txt" # sed -i "${CutEndRow},$d" produziert Fehler … - fi + if [ -n "$CutEnd" ]; then # alles nach dem End-Keyword löschen + CutEndRow=$(cat "${APPDIR}/tmp/${NAME}.txt" | egrep -n "$CutEnd" | cut -d":" -f1 | head -n1) + LineCount=$(cat "${APPDIR}/tmp/${NAME}.txt" | wc -l ) + sed -i "${CutEndRow},${LineCount}d" "${APPDIR}/tmp/${NAME}.txt" # sed -i "${CutEndRow},$d" produziert Fehler … + fi - filesize=$(ls -l "${APPDIR}/tmp/${NAME}.txt" | awk '{ print $5 }') + filesize=$(ls -l "${APPDIR}/tmp/${NAME}.txt" | awk '{ print $5 }') - if [ "$filesize" -eq 0 ]; then - echo "WARUNUNG - Download fehlgeschlagen - ${NAME} wird übersprungen!" - mv "${APPDIR}/tmp/${NAME}_old.txt" "${APPDIR}/tmp/${NAME}.txt" # ggf. alte Datei wiederherstellen - continue - fi + if [ "$filesize" -eq 0 ]; then +# echo "WARUNUNG - Download fehlgeschlagen - ${NAME} wird übersprungen!" + printf "%-${NAMElen}s%s\n" "➜ ${NAME}: " "WARUNUNG - Download fehlgeschlagen - ${NAME} wird übersprungen! [Laufzeit: $(sec_to_time $(expr $(date +%s)-${date_start}) )]" + mv "${APPDIR}/tmp/${NAME}_old.txt" "${APPDIR}/tmp/${NAME}.txt" # ggf. alte Datei wiederherstellen + continue + fi - # 2.: vergleiche Hashes, ggf. Änderung mailen - #--------------------------------------------- - difflog=$(diff -q "${APPDIR}/tmp/${NAME}.txt" "${APPDIR}/tmp/${NAME}_old.txt") +# 2.: vergleiche Hashes, ggf. Änderung mailen +#--------------------------------------------- + difflog=$(diff -q "${APPDIR}/tmp/${NAME}.txt" "${APPDIR}/tmp/${NAME}_old.txt") - file1=$(cat "${APPDIR}/tmp/${NAME}.txt" | sort) - file2=$(cat "${APPDIR}/tmp/${NAME}_old.txt" | sort) + file1=$(cat "${APPDIR}/tmp/${NAME}.txt" | sort) + file2=$(cat "${APPDIR}/tmp/${NAME}_old.txt" | sort) - if [ "$file1" = "$file2" ]; then - echo "keine Änderung" - rm "${APPDIR}/tmp/${NAME}_old.txt" - elif [ $? -eq 1 ]; then - FOUND=1 - echo "Änderung für ${NAME} gefunden" - if [ -f "${APPDIR}/tmp/${NAME}_old.txt" ] ; then - VARDIFF=$(diff "${APPDIR}/tmp/${NAME}_old.txt" "${APPDIR}/tmp/${NAME}.txt" | head -c 10k) # head -c 25k + if [ "$file1" = "$file2" ]; then + printf "%-${NAMElen}s%s\n" "➜ ${NAME}: " "keine Änderung [Laufzeit: $(sec_to_time $(expr $(date +%s)-${date_start}) )]" + rm "${APPDIR}/tmp/${NAME}_old.txt" + elif [ $? -eq 1 ]; then + FOUND=1 + printf "%-${NAMElen}s%s\n" "➜ ${NAME}: " "Änderung für ${NAME} gefunden [Laufzeit: $(sec_to_time $(expr $(date +%s)-${date_start}) )]" + if [ -f "${APPDIR}/tmp/${NAME}_old.txt" ] ; then + VARDIFF=$(diff "${APPDIR}/tmp/${NAME}_old.txt" "${APPDIR}/tmp/${NAME}.txt" | head -c 10k) # head -c 25k - subject="! ! ! ACHTUNG ! ! ! - Änderung für ${NAME} gefunden" - mail="/tmp/ChangeDetectionMailPHP.txt" + subject="! ! ! ACHTUNG ! ! ! - Änderung für ${NAME} gefunden" + mail="/tmp/ChangeDetectionMailPHP.txt" - # ------------------------------------------------------------ - # Mailheader: - echo "To: $EMPFAENGER" > "$mail" - echo "From: $ABSENDER" >> "$mail" - echo "MIME-Version: 1.0" >> "$mail" - echo "Content-Type: multipart/alternative; " >> "$mail" - echo ' boundary="some.unique.value.ABC123/geimist.eu"' >> "$mail" - echo "Subject: $subject" >> "$mail" - echo "" >> "$mail" - echo "This is a MIME-encapsulated message" >> "$mail" - echo "" >> "$mail" - echo "--some.unique.value.ABC123/geimist.eu" >> "$mail" - echo "Content-Type: text/html; charset=UTF-8" >> "$mail" - echo "" >> "$mail" - # Mail-Body: - echo "" >> "$mail" - # ------------------------------------------------------------ - - # Linkkorrektur: - LINK=$( echo "$LINK" | sed "s=${jsServer}==g") + # ------------------------------------------------------------ + # Mailheader: + echo "To: $EMPFAENGER" > "$mail" + echo "From: $ABSENDER" >> "$mail" + echo "MIME-Version: 1.0" >> "$mail" + echo "Content-Type: multipart/alternative; " >> "$mail" + echo ' boundary="some.unique.value.ABC123/geimist.eu"' >> "$mail" + echo "Subject: $subject" >> "$mail" + echo "" >> "$mail" + echo "This is a MIME-encapsulated message" >> "$mail" + echo "" >> "$mail" + echo "--some.unique.value.ABC123/geimist.eu" >> "$mail" + echo "Content-Type: text/html; charset=UTF-8" >> "$mail" + echo "" >> "$mail" + # Mail-Body: + echo "" >> "$mail" + # ------------------------------------------------------------ + # Linkkorrektur: + LINK=$( echo "$LINK" | sed "s=${jsServer}==g") + echo "Es wurden Änderungen auf der Website für ${NAME} gefunden!" >> "$mail" + echo "


Änderungen:

" >> "$mail" - echo "Es wurden Änderungen auf der Website für ${NAME} gefunden!" >> "$mail" - echo "


Änderungen:

" >> "$mail" + # Zeilenumbrüchen, Tabs anpassen / Sonderzeichen maskieren: + echo "${VARDIFF}" | sed '/^---$/d' | sed -e 's/$/
/g ; s/\t/ /g ; s=\/=§1§=g ; s=\*=§2§=g ; s=\[=§3§=g ; s=\]=§4§=g ; s= =§5§=g' >> "$mail" - # Zeilenumbrüchen, Tabs anpassen / Sonderzeichen maskieren: - echo "${VARDIFF}" | sed '/^---$/d' | sed -e 's/$/
/g ; s/\t/ /g ; s=\/=§1§=g ; s=\*=§2§=g ; s=\[=§3§=g ; s=\]=§4§=g ; s= =§5§=g' >> "$mail" + # zeilenweise den HTML-Code anpassen (gelöschte Zeilen) + while read rawline ; do + if echo "$rawline" | egrep -q '^<'; then + newline=$( echo "$rawline" | sed -e 's|^<§5§|§5§|g' | sed -e 's|$|<\\\/s>\<\\\/span>|g' ) + sed -i "s|$rawline|$newline|g" "$mail" + fi + done < "$mail" - # zeilenweise den HTML-Code anpassen (gelöschte Zeilen) - while read rawline ; do - if echo "$rawline" | egrep -q '^<'; then - newline=$( echo "$rawline" | sed -e 's/^/g' | sed -e 's=$=<\\\/s>\<\\\/span>=g' ) - sed -i "s/$rawline/$newline/g" "$mail" - fi - done < "$mail" - - # zeilenweise den HTML-Code anpassen (hinzugefügte Zeilen) - while read rawline ; do - if echo "$rawline" | egrep -q '^>'; then - newline=$( echo "$rawline" | sed -e 's/^>//g' | sed -e 's=$=\<\\\/span>=g' ) - sed -i "s/$rawline/$newline/g" "$mail" - fi - done < "$mail" - - # Body schließen - echo "
- " >> "$mail" - echo "" >> "$mail" - # Maskierungen rückgängig machen: - sed -i -e 's=§5§=\ \;=g ; s=§4§=\]=g ; s=§3§=\[=g ; s=§2§=\*=g ; s=§1§=\/=g' "$mail" - # … 1 … > führt zu Fehler, da die Maskierung …§5§1§5§… zu …§5/5§… demaskiert wird - - if echo "${VARDIFF}" | egrep -qzv "Error|Application is not available|502 Bad Gateway|504 Bad Gateway|504 Gateway Time-out|Service Unavailable|be back shortly|Link: canonical"; then # nur benachrichtigen, sofern kein Error getrackt wurde - # Peep notify: - sleep 1 - echo 2 > /dev/ttyS1; sleep 0.1; echo 2 > /dev/ttyS1 #echo 2 > short beep - sleep 1 - - # Mailen (ssmtp): - ssmtp "$EMPFAENGER" < "$mail" - - # Pushbullet: - if [ ! -z $PBTOKEN ] && [[ ! $PushInfo = noPB ]] ; then - PB_LOG=$(curl --header "Access-Token:${PBTOKEN}" https://api.pushbullet.com/v2/pushes -d type=note -d title="Changedetection (${NAME})" -d body="${VARDIFF}") - echo "$PB_LOG" - if echo "$PB_LOG" | grep -q "error"; then - echo "PushBullet Message:" - echo "${VARDIFF}" - fi - fi - else - echo "↳ aussortierte geloggte Message:" - echo "${VARDIFF}" - mv "${APPDIR}/tmp/${NAME}_old.txt" "${APPDIR}/tmp/${NAME}.txt" # ggf. alte Datei wiederherstellen + # zeilenweise den HTML-Code anpassen (hinzugefügte Zeilen) + while read rawline ; do + if echo "$rawline" | egrep -q '^>'; then +# newline=$( echo "$rawline" | sed -e 's/^>//g' | sed -e 's=$=\<\\\/span>=g' ) + newline=$( echo "$rawline" | sed -e 's|^>||g' | sed -e 's|$|\<\\\/span>|g' ) + sed -i "s|$rawline|$newline|g" "$mail" +# sed -i "s/$rawline/$newline/g" "$mail" fi - # DSM Notification: -# synodsmnotify @administrators "! ! Änderung ${NAME} ! !" "$(cat /tmp/ChangeDetectionMailPHP.txt)" - - # Änderungen archivieren: - mv "${APPDIR}/tmp/${NAME}_old.txt" "${APPDIR}/change_detected/${NAME}_$(date +%Y-%m-%d_%H-%M)_before.txt" - cp "${APPDIR}/tmp/${NAME}.txt" "${APPDIR}/change_detected/${NAME}_$(date +%Y-%m-%d_%H-%M)_current.txt" + done < "$mail" + + # Body schließen + echo "
" >> "$mail" + echo "" >> "$mail" + # Maskierungen rückgängig machen: + sed -i -e 's=§5§=\ \;=g ; s=§4§=\]=g ; s=§3§=\[=g ; s=§2§=\*=g ; s=§1§=\/=g' "$mail" + # … 1 … > führt zu Fehler, da die Maskierung …§5§1§5§… zu …§5/5§… demaskiert wird + if echo "${VARDIFF}" | egrep -qzv "Error|Application is not available|502 Bad Gateway|504 Bad Gateway|504 Gateway Time-out|Service Unavailable|be back shortly|Link: canonical"; then # nur benachrichtigen, sofern kein Error getrackt wurde + # Peep notify: + sleep 1 + echo 2 > /dev/ttyS1; sleep 0.1; echo 2 > /dev/ttyS1 #echo 2 > short beep + sleep 1 + + # Mailen (ssmtp): + ssmtp "$EMPFAENGER" < "$mail" + + # Pushbullet: + if [ ! -z $PBTOKEN ] && [[ ! $PushInfo = noPB ]] ; then + PB_LOG=$(curl --header "Access-Token:${PBTOKEN}" https://api.pushbullet.com/v2/pushes -d type=note -d title="Changedetection (${NAME})" -d body="${VARDIFF}" 2>&1) + echo "$PB_LOG" + if echo "$PB_LOG" | grep -q "error"; then + echo "PushBullet Message:" + echo "${VARDIFF}" + fi + fi + else + echo "↳ aussortierte geloggte Message:" + echo "${VARDIFF}" + mv "${APPDIR}/tmp/${NAME}_old.txt" "${APPDIR}/tmp/${NAME}.txt" # ggf. alte Datei wiederherstellen fi + + # DSM Notification: + synodsmnotify @administrators "! ! Änderung ${NAME} ! !" "$LINK" #"$(cat /tmp/ChangeDetectionMailPHP.txt)" + + # Änderungen archivieren: + mv "${APPDIR}/tmp/${NAME}_old.txt" "${APPDIR}/change_detected/${NAME}_$(date +%Y-%m-%d_%H-%M)_before.txt" + cp "${APPDIR}/tmp/${NAME}.txt" "${APPDIR}/change_detected/${NAME}_$(date +%Y-%m-%d_%H-%M)_current.txt" fi - done < "${APPDIR}/SITES.txt" + fi +done < "${APPDIR}/SITES.txt" # leere Logs löschen: @@ -210,21 +252,20 @@ while read i # Quelle zeilenweise einlesen fi # alte Archivdateien löschen - purge_LOG + purge_LOG ${NAMElen} # if [ "$ERROR" -eq 1 ]; then # echo "WARNUNG: Skript mit Fehlern beendet!" # exit 1 # fi - -exit # Changelog: # 1.1 # - Anpassungen an diff / Verzicht auf cksum -# - Größenbeschränkung der gelogten Änderung auf 100KB +# - Größenbeschränkung der gelogten Änderung (Error: Argument list too long) # 1.2 # - Ausgabe als HTML-formatierte Mail # - archivierte Änderungen werden nach der angegebenen Anzahl von Tagen gelöscht - \ No newline at end of file + +exit \ No newline at end of file