#!/bin/sh # changedetection # v1.2@geimist # 2020-07-12 # /volume1/homes/admin/script/changedetection/changedetection.sh # Definition der Variablen: EMPFAENGER=user@domain.de ABSENDER='Diskstation ' # Name PBTOKEN='' MAXDAY=30 # max. Alter in Tagen für erkannte und archivierte Änderungen #--------------------------------------------- AB HIER NICHTS MEHR ÄNDERN --------------------------------------------- APPDIR=$(cd $(dirname $0);pwd) ERROR=0 FOUND=0 LOGFILE="/volume1/system/@Logfiles/changedetection/changedetection_LOG_$(date +%Y-%m-%d_%H-%M).log" umask 000 # damit Files auch von anderen Usern bearbeitet werden können / http://openbook.rheinwerk-verlag.de/shell_programmierung/shell_011_003.htm if [ ! -d "${APPDIR}/tmp/" ] ; then mkdir "${APPDIR}/tmp" fi if [ ! -d "${APPDIR}/change_detected/" ] ; then mkdir "${APPDIR}/change_detected" fi jsServer="https://render-tron.appspot.com/render/" url2="https://render-tron.appspot.com/render/https://www.rebuy.de/kaufen/apple-iphone-iphone-11-pro?f_prop_rom%5B%5D=256+GB&f_prop_rom%5B%5D=64+GB&f_prop_rom%5B%5D=256+GB&f_prop_rom%5B%5D=64+GB&f_prop_colour_filter%5B%5D=grau&f_prop_colour_filter%5B%5D=gr%C3%BCn&f_prop_colour_filter%5B%5D=silber" # exit purge_LOG() { ######################################################################################### # This function cleans up older log files # ######################################################################################### echo -e if [ -z $MAXDAY ]; then echo "purge_LOG deactivated" return fi anzahl=0 # -maxdepth 1 for del in $(find "${APPDIR}/change_detected/" -type f -mtime +${MAXDAY}); do anzahl=$( expr $anzahl + 1 ) rm -f "$del" done 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) 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 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 }') 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") file1=$(cat "${APPDIR}/tmp/${NAME}.txt" | sort) file2=$(cat "${APPDIR}/tmp/${NAME}_old.txt" | sort) 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" # ------------------------------------------------------------ # 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" # 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 (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 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 fi done < "${APPDIR}/SITES.txt" # leere Logs löschen: if [ $FOUND -eq 0 ]; then rm -f "${LOGFILE}" fi # alte Archivdateien löschen purge_LOG ${NAMElen} # if [ "$ERROR" -eq 1 ]; then # echo "WARNUNG: Skript mit Fehlern beendet!" # exit 1 # fi # Changelog: # 1.1 # - Anpassungen an diff / Verzicht auf cksum # - 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 exit