mirror of
https://github.com/sdr-enthusiasts/docker-planefence.git
synced 2025-12-22 11:17:06 +00:00
improve planefence web table
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
#!/command/with-contenv bash
|
||||
#shellcheck shell=bash
|
||||
#shellcheck disable=SC2015,SC1091,SC2005,SC2006,SC2094
|
||||
#shellcheck disable=SC2015,SC1091,SC2005,SC2006,SC2094,SC2154
|
||||
# PLANETWEET - a Bash shell script to send a Tweet when a plane is detected in the
|
||||
# user-defined fence area.
|
||||
#
|
||||
@@ -35,7 +35,6 @@ source /scripts/common
|
||||
|
||||
[[ -z "$PLANEFENCEDIR" ]] && PLANEFENCEDIR=/usr/share/planefence
|
||||
[[ -f "$PLANEFENCEDIR/planefence.conf" ]] && source "$PLANEFENCEDIR/planefence.conf"
|
||||
APPNAME="$(hostname)/planefence_notify"
|
||||
#
|
||||
# These are the input and output directories and file names
|
||||
# HEADR determines the tags for each of the fields in the Tweet:
|
||||
@@ -65,59 +64,56 @@ PLANEFILE=/usr/share/planefence/persist/plane-alert-db.txt
|
||||
# MINTIME is the minimum time we wait before sending a tweet
|
||||
# to ensure that at least $MINTIME of audio collection (actually limited to the Planefence update runs in this period) to get a more accurste Loudness.
|
||||
|
||||
(( TWEET_MINTIME > 0 )) && MINTIME=$TWEET_MINTIME || MINTIME=100
|
||||
((TWEET_MINTIME > 0)) && MINTIME=$TWEET_MINTIME || MINTIME=100
|
||||
|
||||
# $ATTRIB contains the attribution line at the bottom of the tweet
|
||||
ATTRIB="${ATTRIB:-#adsb #planefence by kx1t - https://sdr-e.com/docker-planefence}"
|
||||
|
||||
if [ "$SOCKETCONFIG" != "" ]
|
||||
then
|
||||
case "$(grep "^distanceunit=" "$SOCKETCONFIG" |sed "s/distanceunit=//g")" in
|
||||
nauticalmile)
|
||||
if [ "$SOCKETCONFIG" != "" ]; then
|
||||
case "$(grep "^distanceunit=" "$SOCKETCONFIG" | sed "s/distanceunit=//g")" in
|
||||
nauticalmile)
|
||||
DISTUNIT="nm"
|
||||
;;
|
||||
kilometer)
|
||||
kilometer)
|
||||
DISTUNIT="km"
|
||||
;;
|
||||
mile)
|
||||
mile)
|
||||
DISTUNIT="mi"
|
||||
;;
|
||||
meter)
|
||||
meter)
|
||||
DISTUNIT="m"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# get ALTITUDE unit:
|
||||
ALTUNIT="ft"
|
||||
if [ "$SOCKETCONFIG" != "" ]
|
||||
then
|
||||
case "$(grep "^altitudeunit=" "$SOCKETCONFIG" |sed "s/altitudeunit=//g")" in
|
||||
feet)
|
||||
if [ "$SOCKETCONFIG" != "" ]; then
|
||||
case "$(grep "^altitudeunit=" "$SOCKETCONFIG" | sed "s/altitudeunit=//g")" in
|
||||
feet)
|
||||
ALTUNIT="ft"
|
||||
;;
|
||||
meter)
|
||||
meter)
|
||||
ALTUNIT="m"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# determine if altitude is ASL or AGL
|
||||
(( ALTCORR > 0 )) && ALTPARAM="AGL" || ALTPARAM="MSL"
|
||||
|
||||
((ALTCORR > 0)) && ALTPARAM="AGL" || ALTPARAM="MSL"
|
||||
|
||||
# -----------------------------------------------------------------------------------
|
||||
# -----------------------------------------------------------------------------------
|
||||
#
|
||||
# First create an function to write to the log
|
||||
LOG ()
|
||||
{ if [ "$VERBOSE" != "" ]
|
||||
then
|
||||
printf "%s-%s[%s]v%s: %s\n" "$(date +"%Y%m%d-%H%M%S")" "$PROCESS_NAME" "$CURRENT_PID" "$VERSION" "$1" >> $LOGFILE
|
||||
fi
|
||||
LOG() {
|
||||
if [ "$VERBOSE" != "" ]; then
|
||||
printf "%s-%s[%s]v%s: %s\n" "$(date +"%Y%m%d-%H%M%S")" "$PROCESS_NAME" "$CURRENT_PID" "$VERSION" "$1" >>$LOGFILE
|
||||
fi
|
||||
}
|
||||
|
||||
getRoute()
|
||||
{
|
||||
# Uses MrJackWills's API to look up flight information based on Callsign. See https://github.com/mrjackwills/adsbdb
|
||||
getRoute() {
|
||||
# Uses MrJackWills's API to look up flight information based on Callsign. See https://github.com/mrjackwills/adsbdb
|
||||
# Usage: routeString="$(getRoute "$CallSign")"
|
||||
#
|
||||
# Returns a string:
|
||||
@@ -125,11 +121,10 @@ getRoute()
|
||||
# if only either Origin or Destination airport are known: "org: #BOS" or "dest: #JFK"
|
||||
# if neither is available: empty string
|
||||
#
|
||||
# Prerequisites/dependencies: JQ, CURL
|
||||
# Prerequisites/dependencies: JQ, CURL
|
||||
|
||||
# first make sure we have an argument
|
||||
if [[ -z "$1" ]]
|
||||
then
|
||||
if [[ -z "$1" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
@@ -137,24 +132,20 @@ getRoute()
|
||||
routeObj="$(curl -sL "https://api.adsbdb.com/v0/callsign/$1")"
|
||||
|
||||
# Unknown Call -> return empty
|
||||
if [[ "$(jq '.response' <<< "$routeObj")" == "\"unknown callsign\"" ]]
|
||||
then
|
||||
if [[ "$(jq '.response' <<<"$routeObj")" == "\"unknown callsign\"" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# Get origin/dest:
|
||||
origin="$(jq '.response.flightroute.origin.iata_code' 2>/dev/null <<< "$routeObj"|tr -d '\"')"
|
||||
destination="$(jq '.response.flightroute.destination.iata_code' 2>/dev/null <<< "$routeObj"|tr -d '\"')"
|
||||
origin="$(jq '.response.flightroute.origin.iata_code' 2>/dev/null <<<"$routeObj" | tr -d '\"')"
|
||||
destination="$(jq '.response.flightroute.destination.iata_code' 2>/dev/null <<<"$routeObj" | tr -d '\"')"
|
||||
response=""
|
||||
|
||||
if [[ -n "$origin" ]] && [[ -n "$destination" ]]
|
||||
then
|
||||
if [[ -n "$origin" ]] && [[ -n "$destination" ]]; then
|
||||
response="#$origin - #$destination"
|
||||
elif [[ -n "$origin" ]]
|
||||
then
|
||||
elif [[ -n "$origin" ]]; then
|
||||
response="org: #$origin"
|
||||
elif [[ -n "$destination" ]]
|
||||
then
|
||||
elif [[ -n "$destination" ]]; then
|
||||
response="dest: #$destination"
|
||||
fi
|
||||
|
||||
@@ -162,9 +153,8 @@ getRoute()
|
||||
echo "$response"
|
||||
}
|
||||
|
||||
if [ "$1" != "" ] && [ "$1" != "reset" ]
|
||||
then # $1 contains the date for which we want to run PlaneFence
|
||||
TWEETDATE=$(date --date="$1" '+%y%m%d')
|
||||
if [ "$1" != "" ] && [ "$1" != "reset" ]; then # $1 contains the date for which we want to run PlaneFence
|
||||
TWEETDATE=$(date --date="$1" '+%y%m%d')
|
||||
else
|
||||
TWEETDATE=$(date --date="today" '+%y%m%d')
|
||||
fi
|
||||
@@ -184,51 +174,43 @@ LOG "CSVFILE=$CSVFILE"
|
||||
# Get the hashtaggable headers, and figure out of there is a field with a
|
||||
# custom "$tag" header
|
||||
|
||||
[[ -f "$PLANEFILE" ]] && IFS="," read -ra hashtag < $PLANEFILE || unset hashtag
|
||||
[[ -f "$PLANEFILE" ]] && IFS="," read -ra hashtag <$PLANEFILE || unset hashtag
|
||||
tagfield=""
|
||||
for ((i = 0 ; i < ${#hashtag[@]} ; i++))
|
||||
do
|
||||
if [[ "${hashtag[i],,}" == "\$tag" ]] || [[ "${hashtag[i],,}" == "#\$tag" ]]
|
||||
then
|
||||
tagfield=$((i+1)) # number tagfield from 1 instead of 0 as we will use AWK to get it
|
||||
break;
|
||||
for ((i = 0; i < ${#hashtag[@]}; i++)); do
|
||||
if [[ "${hashtag[i],,}" == "\$tag" ]] || [[ "${hashtag[i],,}" == "#\$tag" ]]; then
|
||||
tagfield=$((i + 1)) # number tagfield from 1 instead of 0 as we will use AWK to get it
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -f "$CSVFILE" ]
|
||||
then
|
||||
while read -r CSVLINE
|
||||
do
|
||||
if [ -f "$CSVFILE" ]; then
|
||||
while read -r CSVLINE; do
|
||||
XX=$(echo -n "$CSVLINE" | tr -d '[:cntrl:]')
|
||||
CSVLINE=$XX
|
||||
unset RECORD
|
||||
# Read the line, but first clean it up as it appears to have a newline in it
|
||||
IFS="," read -ra RECORD <<< "$CSVLINE"
|
||||
IFS="," read -ra RECORD <<<"$CSVLINE"
|
||||
# LOG "${#RECORD[*]} records in the current line: (${RECORD[*]})"
|
||||
# $TIMEDIFF contains the difference in seconds between the current record and "now".
|
||||
# We want this to be at least $MINDIFF to avoid tweeting before all noise data is captured
|
||||
# $TWEET_BEHAVIOR determines if we are looking at the end time (POST -> RECORD[3]) or at the
|
||||
# start time (not POST -> RECORD[2]) of the observation time
|
||||
[[ "$TWEET_BEHAVIOR" == "POST" ]] && TIMEDIFF=$(( $(date +%s) - $(date -d "${RECORD[3]}" +%s) )) || TIMEDIFF=$(( $(date +%s) - $(date -d "${RECORD[2]}" +%s) ))
|
||||
[[ "$TWEET_BEHAVIOR" == "POST" ]] && TIMEDIFF=$(($(date +%s) - $(date -d "${RECORD[3]}" +%s))) || TIMEDIFF=$(($(date +%s) - $(date -d "${RECORD[2]}" +%s)))
|
||||
|
||||
# shellcheck disable=SC2126
|
||||
# shellcheck disable=SC2094
|
||||
if [[ "${RECORD[1]:0:1}" != "@" ]] && [[ $TIMEDIFF -gt $MINTIME ]] && [[ ( "$(grep "${RECORD[0]},@${RECORD[1]}" "$CSVFILE" | wc -l)" == "0" ) || "$TWEETEVERY" == "true" ]]
|
||||
# ^not tweeted before^ ^older than $MINTIME^ ^No previous occurrence that was tweeted^ ...or... ^$TWEETEVERY is true^
|
||||
then
|
||||
if [[ "${RECORD[1]:0:1}" != "@" ]] && [[ $TIMEDIFF -gt $MINTIME ]] && [[ ("$(grep "${RECORD[0]},@${RECORD[1]}" "$CSVFILE" | wc -l)" == "0") || "$TWEETEVERY" == "true" ]]; then # ^not tweeted before^ ^older than $MINTIME^ ^No previous occurrence that was tweeted^ ...or... ^$TWEETEVERY is true^
|
||||
|
||||
AIRLINE=$(/usr/share/planefence/airlinename.sh "${RECORD[1]#@}" "${RECORD[0]}" )
|
||||
AIRLINE=$(/usr/share/planefence/airlinename.sh "${RECORD[1]#@}" "${RECORD[0]}")
|
||||
AIRLINETAG="#"
|
||||
if [[ "${RECORD[1]}" != "" ]]
|
||||
then
|
||||
if [[ "${RECORD[1]}" != "" ]]; then
|
||||
AIRLINETAG+="$(echo "$AIRLINE" | tr -d '[:space:]-')"
|
||||
ROUTE="$(getRoute "${RECORD[1]}")"
|
||||
fi
|
||||
|
||||
# Create a Tweet with the first 6 fields, each of them followed by a Newline character
|
||||
[[ "${hashtag[0]:0:1}" == "$" ]] && TWEET="${HEADR[0]}: #${RECORD[0]}%0A" || TWEET="${HEADR[0]}: ${RECORD[0]}%0A" # ICAO
|
||||
if [[ "${RECORD[1]}" != "" ]]
|
||||
then
|
||||
if [[ "${RECORD[1]}" != "" ]]; then
|
||||
[[ "${hashtag[1]:0:1}" == "$" ]] && TWEET+="${HEADR[1]}: #${RECORD[1]//-/}" || TWEET+="${HEADR[1]}: ${RECORD[1]}" # Flight
|
||||
fi
|
||||
[[ "$AIRLINETAG" != "#" ]] && TWEET+=" ${AIRLINETAG//[&\'-]/_}" || true
|
||||
@@ -239,7 +221,7 @@ then
|
||||
|
||||
# If there is sound level data, then add a Loudness factor (peak RMS - 1 hr avg) to the tweet.
|
||||
# There is more data we could tweet, but we're a bit restricted in real estate on twitter.
|
||||
(( RECORD[7] < 0 )) && TWEET+="${HEADR[9]}: ${RECORD[7]} dBFS%0A${HEADR[8]}: $(( RECORD[7] - RECORD[11] )) dB%0A"
|
||||
((RECORD[7] < 0)) && TWEET+="${HEADR[9]}: ${RECORD[7]} dBFS%0A${HEADR[8]}: $((RECORD[7] - RECORD[11])) dB%0A"
|
||||
|
||||
# figure out of there are custom tags that apply to this ICAO:
|
||||
[[ "$tagfield" != "" ]] && customtag="$(awk -F "," -v field="$tagfield" -v icao="${RECORD[0]}" '$1 == icao {print $field; exit;}' "$PLANEFILE")" || customtag=""
|
||||
@@ -253,15 +235,15 @@ then
|
||||
TWEET="${TWEET//globe.adsbexchange.com/"$TRACKSERVICE"}"
|
||||
|
||||
# let's do some calcs on the actual tweet length, so we strip the minimum:
|
||||
teststring="${TWEET//%0A/ }" # replace newlines with a single character
|
||||
teststring="$(sed 's/https\?:\/\/[^ ]*\s/12345678901234567890123 /g' <<< "$teststring ")" # replace all URLS with 23 spaces - note the extra space after the string
|
||||
tweetlength=$(( ${#teststring} - 1 ))
|
||||
if (( tweetlength > 490 )); then
|
||||
echo "[$(date)][$APPNAME] Warning: PF tweet length is $tweetlength > 490: tweet will be truncated!"
|
||||
maxlength=$(( ${#TWEET} + 490 - tweetlength ))
|
||||
teststring="${TWEET//%0A/ }" # replace newlines with a single character
|
||||
teststring="$(sed 's/https\?:\/\/[^ ]*\s/12345678901234567890123 /g' <<<"$teststring ")" # replace all URLS with 23 spaces - note the extra space after the string
|
||||
tweetlength=$((${#teststring} - 1))
|
||||
if ((tweetlength > 490)); then
|
||||
"${s6wrap[@]}" echo "Warning: PF tweet length is $tweetlength > 490: tweet will be truncated!"
|
||||
maxlength=$((${#TWEET} + 490 - tweetlength))
|
||||
TWEET="${TWEET:0:$maxlength}"
|
||||
fi
|
||||
|
||||
|
||||
LOG "Assessing ${RECORD[0]}: ${RECORD[1]:0:1}; diff=$TIMEDIFF secs; Tweeting... msg body: $TWEET" 1
|
||||
|
||||
# Before anything else, let's add the "tweeted" flag to the flight number:
|
||||
@@ -275,59 +257,51 @@ then
|
||||
|
||||
newsnap="$(find /usr/share/planefence/persist/planepix -iname "${RECORD[0]}.jpg" -print -quit 2>/dev/null || true)"
|
||||
# echo "-0- in planetweet: newsnap=\"$newsnap\" (find /usr/share/planefence/persist/planepix -iname ${RECORD[0]}.jpg -print -quit)"
|
||||
if [[ "$newsnap" != "" ]]
|
||||
then
|
||||
if [[ "$newsnap" != "" ]]; then
|
||||
GOTSNAP="true"
|
||||
rm -f "$snapfile"
|
||||
ln -sf "$newsnap" "$snapfile"
|
||||
echo "[$(date)][$APPNAME] Using picture from $newsnap"
|
||||
"${s6wrap[@]}" echo "Using picture from $newsnap"
|
||||
else
|
||||
link=$(awk -F "," -v icao="${RECORD[0],,}" 'tolower($1) == icao { print $2 ; exit }' /usr/share/planefence/persist/planepix.txt 2>/dev/null || true)
|
||||
if [[ "$link" != "" ]] && curl -A "Mozilla/5.0 (X11; Linux x86_64; rv:97.0) Gecko/20100101 Firefox/97.0" -s -L --fail "$link" -o $snapfile --show-error 2>/dev/stdout
|
||||
then
|
||||
echo "[$(date)][$APPNAME] Using picture from $link"
|
||||
if [[ "$link" != "" ]] && curl -A "Mozilla/5.0 (X11; Linux x86_64; rv:97.0) Gecko/20100101 Firefox/97.0" -s -L --fail "$link" -o $snapfile --show-error 2>/dev/stdout; then
|
||||
"${s6wrap[@]}" echo "Using picture from $link"
|
||||
GOTSNAP="true"
|
||||
[[ ! -f "/usr/share/planefence/persist/planepix/${RECORD[0]}.jpg" ]] && cp "$snapfile" "/usr/share/planefence/persist/planepix/${RECORD[0]}.jpg" || true
|
||||
else
|
||||
[[ "$link" != "" ]] && echo "[$(date)][$APPNAME] Failed attempt to get picture from $link" || true
|
||||
[[ "$link" != "" ]] && "${s6wrap[@]}" echo "Failed attempt to get picture from $link" || true
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$GOTSNAP" == "false" ]] && curl -s -L --fail --max-time "$SCREENSHOT_TIMEOUT" "$SCREENSHOTURL/snap/${RECORD[0]#\#}" -o "/tmp/snapshot.png"
|
||||
then
|
||||
"${s6wrap[@]}" echo "Getting screenshot for ${RECORD[0]}..."
|
||||
if [[ "$GOTSNAP" == "false" ]] && curl -s -L --fail --max-time "$SCREENSHOT_TIMEOUT" "$SCREENSHOTURL/snap/${RECORD[0]#\#}" -o "/tmp/snapshot.png"; then
|
||||
GOTSNAP="true"
|
||||
echo "[$(date)][$APPNAME] Screenshot successfully retrieved at $SCREENSHOTURL for ${RECORD[0]}"
|
||||
"${s6wrap[@]}" echo "Screenshot successfully retrieved at $SCREENSHOTURL for ${RECORD[0]}"
|
||||
fi
|
||||
[[ "$GOTSNAP" == "false" ]] && echo "[$(date)][$APPNAME] Screenshot retrieval unsuccessful at $SCREENSHOTURL for ${RECORD[0]}" || true
|
||||
[[ "$GOTSNAP" == "false" ]] && "${s6wrap[@]}" echo "Screenshot retrieval unsuccessful at $SCREENSHOTURL for ${RECORD[0]}" || true
|
||||
|
||||
# Inject the Discord integration in here so it doesn't have to worry about state management
|
||||
if [[ "${PF_DISCORD,,}" == "on" || "${PF_DISCORD,,}" == "true" ]] && [[ "x$PF_DISCORD_WEBHOOKS" != "x" ]] && [[ "x$DISCORD_FEEDER_NAME" != "x" ]]
|
||||
then
|
||||
if [[ "${PF_DISCORD,,}" == "on" || "${PF_DISCORD,,}" == "true" ]] && [[ "x$PF_DISCORD_WEBHOOKS" != "x" ]] && [[ "x$DISCORD_FEEDER_NAME" != "x" ]]; then
|
||||
LOG "Planefence sending Discord notification"
|
||||
timeout 120 python3 "$PLANEFENCEDIR"/send-discord-alert.py "$CSVLINE" "$AIRLINE"
|
||||
fi
|
||||
timeout 120 python3 "$PLANEFENCEDIR"/send-discord-alert.py "$CSVLINE" "$AIRLINE"
|
||||
fi
|
||||
|
||||
# log the message we will try to tweet or toot:
|
||||
if [[ -n "$MASTODON_SERVER" ]] || [ "$TWEETON" == "yes" ]
|
||||
then
|
||||
echo "[$(date)][$APPNAME] Attempting to tweet or toot: $(sed -e 's|\\/|/|g' -e 's|\\n| |g' -e 's|%0A| |g' <<< "${TWEET}")"
|
||||
if [[ -n "$MASTODON_SERVER" ]] || [ "$TWEETON" == "yes" ]; then
|
||||
"${s6wrap[@]}" echo "Attempting to tweet or toot: $(sed -e 's|\\/|/|g' -e 's|\\n| |g' -e 's|%0A| |g' <<<"${TWEET}")"
|
||||
fi
|
||||
# Inject Mastodon integration here:
|
||||
if [[ -n "$MASTODON_SERVER" ]]
|
||||
then
|
||||
if [[ -n "$MASTODON_SERVER" ]]; then
|
||||
mast_id="null"
|
||||
MASTTEXT="$(sed -e 's|\\/|/|g' -e 's|\\n|\n|g' -e 's|%0A|\n|g' <<< "${TWEET}")"
|
||||
|
||||
if [[ "$GOTSNAP" == "true" ]]
|
||||
then
|
||||
MASTTEXT="$(sed -e 's|\\/|/|g' -e 's|\\n|\n|g' -e 's|%0A|\n|g' <<<"${TWEET}")"
|
||||
|
||||
if [[ "$GOTSNAP" == "true" ]]; then
|
||||
# we upload an image
|
||||
response="$(curl -sS -H "Authorization: Bearer ${MASTODON_ACCESS_TOKEN}" -H "Content-Type: multipart/form-data" -X POST "https://${MASTODON_SERVER}/api/v1/media" --form file="@${snapfile}")"
|
||||
mast_id="$(jq '.id' <<< "$response"|xargs)"
|
||||
mast_id="$(jq '.id' <<<"$response" | xargs)"
|
||||
fi
|
||||
|
||||
# now send the message. API is different if text-only vs text+image:
|
||||
if [[ "${mast_id,,}" == "null" ]]
|
||||
then
|
||||
if [[ "${mast_id,,}" == "null" ]]; then
|
||||
# send without image
|
||||
response="$(curl -H "Authorization: Bearer ${MASTODON_ACCESS_TOKEN}" -sS "https://${MASTODON_SERVER}/api/v1/statuses" -X POST -F "status=${MASTTEXT}" -F "language=eng" -F "visibility=${MASTODON_VISIBILITY}")"
|
||||
else
|
||||
@@ -336,12 +310,11 @@ then
|
||||
fi
|
||||
|
||||
# check if there was an error
|
||||
if [[ "$(jq '.error' <<< "$response"|xargs)" == "null" ]]
|
||||
then
|
||||
echo "[$(date)][$APPNAME] Planefence post to Mastodon generated successfully with visibility=${MASTODON_VISIBILITY}. Mastodon post available at: $(jq '.url' <<< "$response"|xargs)"
|
||||
(( RECORD[7] < 0 )) && RECORD[12]="$(jq '.url' <<< "${response}"|xargs)" || RECORD[7]="$(jq '.url' <<< "${response}"|xargs)"
|
||||
if [[ "$(jq '.error' <<<"$response" | xargs)" == "null" ]]; then
|
||||
"${s6wrap[@]}" echo "Planefence post to Mastodon generated successfully with visibility=${MASTODON_VISIBILITY}. Mastodon post available at: $(jq '.url' <<<"$response" | xargs)"
|
||||
LINK="$(jq '.url' <<<"${response}" | xargs)" || RECORD[7]="$(jq '.url' <<<"${response}" | xargs)"
|
||||
else
|
||||
echo "[$(date)][$APPNAME] Mastodon post error. Mastodon returned this error: $(jq '.url' <<< "$response"|xargs)"
|
||||
"${s6wrap[@]}" echo "Mastodon post error. Mastodon returned this error: $(jq '.url' <<<"$response" | xargs)"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -354,9 +327,11 @@ then
|
||||
msg_array[flight]="${RECORD[1]#@}"
|
||||
msg_array[operator]="$(echo "${AIRLINE}" | xargs)"
|
||||
if [[ -n "$ROUTE" ]]; then
|
||||
if [[ "${ROUTE:0:4}" == "org:" ]]; then msg_array[origin]="${ROUTE:6}"
|
||||
elif [[ "${ROUTE:0:5}" == "dest:" ]]; then msg_array[destination]="${ROUTE:7}"
|
||||
else
|
||||
if [[ "${ROUTE:0:4}" == "org:" ]]; then
|
||||
msg_array[origin]="${ROUTE:6}"
|
||||
elif [[ "${ROUTE:0:5}" == "dest:" ]]; then
|
||||
msg_array[destination]="${ROUTE:7}"
|
||||
else
|
||||
msg_array[origin]="${ROUTE:1:3}"
|
||||
msg_array[destination]="${ROUTE: -3}"
|
||||
fi
|
||||
@@ -366,99 +341,94 @@ then
|
||||
msg_array[min_alt]="${RECORD[4]} $ALTUNIT $ALTPARAM"
|
||||
msg_array[min_dist]="${RECORD[5]} $DISTUNIT"
|
||||
msg_array[link]="${RECORD[6]//globe.adsbexchange.com/$TRACKSERVICE}"
|
||||
if (( RECORD[7] < 0 )); then
|
||||
if ((RECORD[7] < 0)); then
|
||||
msg_array[peek_audio]="${RECORD[7]} dBFS"
|
||||
msg_array[loudness]="$(( RECORD[7] - RECORD[11] )) dB"
|
||||
msg_array[loudness]="$((RECORD[7] - RECORD[11])) dB"
|
||||
fi
|
||||
|
||||
# convert $msg_array[@] into a JSON object:
|
||||
MQTT_JSON="$(for i in "${!msg_array[@]}"; do printf '{"%s":"%s"}\n' "$i" "${msg_array[$i]}"; done | jq -sc add)"
|
||||
|
||||
# prep the MQTT host, port, etc
|
||||
unset MQTT_TOPIC MQTT_PORT MQTT_USERNAME MQTT_PASSWORD MQTT_HOST
|
||||
MQTT_HOST="${MQTT_URL,,}"
|
||||
MQTT_HOST="${MQTT_HOST##*:\/\/}" # strip protocol header (mqtt:// etc)
|
||||
while [[ "${MQTT_HOST: -1}" == "/" ]]; do MQTT_HOST="${MQTT_HOST:0: -1}"; done # remove any trailing / from the HOST
|
||||
if [[ $MQTT_HOST == *"/"* ]]; then MQTT_TOPIC="${MQTT_TOPIC:-${MQTT_HOST#*\/}}"; fi # if there's no explicitly defined topic, then use the URL's topic if that exists
|
||||
MQTT_TOPIC="${MQTT_TOPIC:-$(hostname)/planefence}" # add default topic if there is still none defined
|
||||
MQTT_HOST="${MQTT_HOST%%/*}" # remove everything from the first / onward
|
||||
# prep the MQTT host, port, etc
|
||||
unset MQTT_TOPIC MQTT_PORT MQTT_USERNAME MQTT_PASSWORD MQTT_HOST
|
||||
MQTT_HOST="${MQTT_URL,,}"
|
||||
MQTT_HOST="${MQTT_HOST##*:\/\/}" # strip protocol header (mqtt:// etc)
|
||||
while [[ "${MQTT_HOST: -1}" == "/" ]]; do MQTT_HOST="${MQTT_HOST:0:-1}"; done # remove any trailing / from the HOST
|
||||
if [[ $MQTT_HOST == *"/"* ]]; then MQTT_TOPIC="${MQTT_TOPIC:-${MQTT_HOST#*\/}}"; fi # if there's no explicitly defined topic, then use the URL's topic if that exists
|
||||
MQTT_TOPIC="${MQTT_TOPIC:-$(hostname)/planefence}" # add default topic if there is still none defined
|
||||
MQTT_HOST="${MQTT_HOST%%/*}" # remove everything from the first / onward
|
||||
|
||||
if [[ $MQTT_HOST == *"@"* ]]; then
|
||||
MQTT_USERNAME="${MQTT_USERNAME:-${MQTT_HOST%@*}}"
|
||||
MQTT_PASSWORD="${MQTT_PASSWORD:-${MQTT_USERNAME#*:}}"
|
||||
MQTT_USERNAME="${MQTT_USERNAME%:*}"
|
||||
MQTT_HOST="${MQTT_HOST#*@}"
|
||||
fi
|
||||
if [[ $MQTT_HOST == *":"* ]]; then MQTT_PORT="${MQTT_PORT:-${MQTT_HOST#*:}}"; fi
|
||||
MQTT_HOST="${MQTT_HOST%:*}" # finally strip the host so there's only a hostname or ip address
|
||||
if [[ $MQTT_HOST == *"@"* ]]; then
|
||||
MQTT_USERNAME="${MQTT_USERNAME:-${MQTT_HOST%@*}}"
|
||||
MQTT_PASSWORD="${MQTT_PASSWORD:-${MQTT_USERNAME#*:}}"
|
||||
MQTT_USERNAME="${MQTT_USERNAME%:*}"
|
||||
MQTT_HOST="${MQTT_HOST#*@}"
|
||||
fi
|
||||
if [[ $MQTT_HOST == *":"* ]]; then MQTT_PORT="${MQTT_PORT:-${MQTT_HOST#*:}}"; fi
|
||||
MQTT_HOST="${MQTT_HOST%:*}" # finally strip the host so there's only a hostname or ip address
|
||||
|
||||
|
||||
# log the message we are going to send:
|
||||
echo "[$(date)][$APPNAME] Attempting to send a MQTT notification:"
|
||||
echo "[$(date)][$APPNAME] MQTT Host: $MQTT_HOST"
|
||||
echo "[$(date)][$APPNAME] MQTT Port: ${MQTT_PORT:-1883}"
|
||||
echo "[$(date)][$APPNAME] MQTT Topic: $MQTT_TOPIC"
|
||||
echo "[$(date)][$APPNAME] MQTT Client ID: ${MQTT_CLIENT_ID:-$(hostname)}"
|
||||
if [[ -n "$MQTT_USERNAME" ]]; then echo "[$(date)][$APPNAME] MQTT Username: $MQTT_USERNAME"; fi
|
||||
if [[ -n "$MQTT_PASSWORD" ]]; then echo "[$(date)][$APPNAME] MQTT Password: $MQTT_PASSWORD"; fi
|
||||
if [[ -n "$MQTT_QOS" ]]; then echo "[$(date)][$APPNAME] MQTT QOS: $MQTT_QOS"; fi
|
||||
echo "[$(date)][$APPNAME] MQTT Payload JSON Object: $MQTT_JSON"
|
||||
# log the message we are going to send:
|
||||
"${s6wrap[@]}" echo "Attempting to send a MQTT notification:"
|
||||
"${s6wrap[@]}" echo "MQTT Host: $MQTT_HOST"
|
||||
"${s6wrap[@]}" echo "MQTT Port: ${MQTT_PORT:-1883}"
|
||||
"${s6wrap[@]}" echo "MQTT Topic: $MQTT_TOPIC"
|
||||
"${s6wrap[@]}" echo "MQTT Client ID: ${MQTT_CLIENT_ID:-$(hostname)}"
|
||||
if [[ -n "$MQTT_USERNAME" ]]; then "${s6wrap[@]}" echo "MQTT Username: $MQTT_USERNAME"; fi
|
||||
if [[ -n "$MQTT_PASSWORD" ]]; then "${s6wrap[@]}" echo "MQTT Password: $MQTT_PASSWORD"; fi
|
||||
if [[ -n "$MQTT_QOS" ]]; then "${s6wrap[@]}" echo "MQTT QOS: $MQTT_QOS"; fi
|
||||
"${s6wrap[@]}" echo "MQTT Payload JSON Object: $MQTT_JSON"
|
||||
|
||||
# send the MQTT message:
|
||||
mqtt_string=(--broker "$MQTT_HOST")
|
||||
if [[ -n "$MQTT_PORT" ]]; then mqtt_string+=(--port "$MQTT_PORT"); fi
|
||||
mqtt_string+=(--topic \""$MQTT_TOPIC"\")
|
||||
if [[ -n "$MQTT_QOS" ]]; then mqtt_string+=(--qos "$MQTT_QOS"); fi
|
||||
mqtt_string+=(--client_id \""${MQTT_CLIENT_ID:-$(hostname)}"\")
|
||||
if [[ -n "$MQTT_USERNAME" ]]; then mqtt_string+=(--username "$MQTT_USERNAME"); fi
|
||||
if [[ -n "$MQTT_PASSWORD" ]]; then mqtt_string+=(--password "$MQTT_PASSWORD"); fi
|
||||
mqtt_string+=(--message "'${MQTT_JSON}'")
|
||||
# send the MQTT message:
|
||||
mqtt_string=(--broker "$MQTT_HOST")
|
||||
if [[ -n "$MQTT_PORT" ]]; then mqtt_string+=(--port "$MQTT_PORT"); fi
|
||||
mqtt_string+=(--topic \""$MQTT_TOPIC"\")
|
||||
if [[ -n "$MQTT_QOS" ]]; then mqtt_string+=(--qos "$MQTT_QOS"); fi
|
||||
mqtt_string+=(--client_id \""${MQTT_CLIENT_ID:-$(hostname)}"\")
|
||||
if [[ -n "$MQTT_USERNAME" ]]; then mqtt_string+=(--username "$MQTT_USERNAME"); fi
|
||||
if [[ -n "$MQTT_PASSWORD" ]]; then mqtt_string+=(--password "$MQTT_PASSWORD"); fi
|
||||
mqtt_string+=(--message "'${MQTT_JSON}'")
|
||||
|
||||
# shellcheck disable=SC2068
|
||||
outputmsg="$(echo ${mqtt_string[@]} | xargs mqtt)"
|
||||
# shellcheck disable=SC2068
|
||||
outputmsg="$(echo ${mqtt_string[@]} | xargs mqtt)"
|
||||
|
||||
if [[ "${outputmsg:0:6}" == "Failed" ]] || [[ "${outputmsg:0:5}" == "usage" ]] ; then
|
||||
echo "[$(date)][$APPNAME] MQTT Delivery Error: ${outputmsg//$'\n'/ }"
|
||||
else
|
||||
echo "[$(date)][$APPNAME] MQTT Delivery successful!"
|
||||
if chk_enabled "$MQTT_DEBUG"; then echo "[$(date)][$APPNAME] Results string: ${outputmsg//$'\n'/ }"; fi
|
||||
fi
|
||||
if [[ "${outputmsg:0:6}" == "Failed" ]] || [[ "${outputmsg:0:5}" == "usage" ]]; then
|
||||
"${s6wrap[@]}" echo "MQTT Delivery Error: ${outputmsg//$'\n'/ }"
|
||||
else
|
||||
"${s6wrap[@]}" echo "MQTT Delivery successful!"
|
||||
if chk_enabled "$MQTT_DEBUG"; then "${s6wrap[@]}" echo "Results string: ${outputmsg//$'\n'/ }"; fi
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# Insert BlueSky notifications here:
|
||||
if [[ -n "$BLUESKY_HANDLE" ]] && [[ -n "$BLUESKY_APP_PASSWORD" ]]; then
|
||||
/scripts/post2bsky.sh "#Planefence $(sed -e 's|\\/|/|g' -e 's|\\n|\n|g' -e 's|%0A|\n|g' <<< "${TWEET}")" "$(if [[ "$GOTSNAP" == "true" ]]; then echo "$snapfile"; fi)" || true
|
||||
/scripts/post2bsky.sh "#Planefence $(sed -e 's|\\/|/|g' -e 's|\\n|\n|g' -e 's|%0A|\n|g' <<<"${TWEET}")" "$(if [[ "$GOTSNAP" == "true" ]]; then echo "$snapfile"; fi)" || true
|
||||
if [[ -f /tmp/bsky.link ]]; then
|
||||
LINK="$(</tmp/bsky.link)"
|
||||
(( RECORD[7] < 0 )) && RECORD[12]="$LINK" || RECORD[7]="$LINK"
|
||||
rm -f /tmp/bsky.link
|
||||
fi
|
||||
fi
|
||||
|
||||
# And now, let's tweet!
|
||||
if [ "$TWEETON" == "yes" ]
|
||||
then
|
||||
if [ "$TWEETON" == "yes" ]; then
|
||||
TWIMG="false"
|
||||
if [[ "$GOTSNAP" == "true" ]]
|
||||
then
|
||||
if [[ "$GOTSNAP" == "true" ]]; then
|
||||
# If the curl call succeeded, we have a snapshot.png file saved!
|
||||
TW_MEDIA_ID=$(twurl -X POST -H upload.twitter.com "/1.1/media/upload.json" -f $snapfile -F media | sed -n 's/.*\"media_id\":\([0-9]*\).*/\1/p')
|
||||
(( TW_MEDIA_ID > 0 )) && TWIMG="true" || TW_MEDIA_ID=""
|
||||
((TW_MEDIA_ID > 0)) && TWIMG="true" || TW_MEDIA_ID=""
|
||||
fi
|
||||
|
||||
[[ "$TWIMG" == "true" ]] && echo "[$(date)][$APPNAME] Twitter Media ID=$TW_MEDIA_ID" || echo "[$(date)][$APPNAME] Twitter screenshot upload unsuccessful for ${RECORD[0]}"
|
||||
[[ "$TWIMG" == "true" ]] && "${s6wrap[@]}" echo "Twitter Media ID=$TW_MEDIA_ID" || "${s6wrap[@]}" echo "Twitter screenshot upload unsuccessful for ${RECORD[0]}"
|
||||
|
||||
# send a tweet and read the link to the tweet into ${LINK[1]}
|
||||
if [[ "$TWIMG" == "true" ]]
|
||||
then
|
||||
LINK="$(echo "`twurl -r "status=$TWEET&media_ids=$TW_MEDIA_ID" /1.1/statuses/update.json`" | tee -a /tmp/tweets.log | jq '.entities."urls" | .[] | .url' | tr -d '\"')"
|
||||
if [[ "$TWIMG" == "true" ]]; then
|
||||
LINK="$(echo "$(twurl -r "status=$TWEET&media_ids=$TW_MEDIA_ID" /1.1/statuses/update.json)" | tee -a /tmp/tweets.log | jq '.entities."urls" | .[] | .url' | tr -d '\"')"
|
||||
else
|
||||
LINK="$(echo "`twurl -r "status=$TWEET" /1.1/statuses/update.json`" | tee -a /tmp/tweets.log | jq '.entities."urls" | .[] | .url' | tr -d '\"')"
|
||||
LINK="$(echo "$(twurl -r "status=$TWEET" /1.1/statuses/update.json)" | tee -a /tmp/tweets.log | jq '.entities."urls" | .[] | .url' | tr -d '\"')"
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2028
|
||||
[[ "${LINK:0:12}" == "https://t.co" ]] && echo "[$(date)][$APPNAME] Planefence post to Twitter generated successfully. Tweet available at: $LINK" || echo "[$(date)][$APPNAME] PlaneFence Tweet error. Twitter returned:\n$(tail -1 /tmp/tweets.log)"
|
||||
[[ "${LINK:0:12}" == "https://t.co" ]] && "${s6wrap[@]}" echo "Planefence post to Twitter generated successfully. Tweet available at: $LINK" || "${s6wrap[@]}" echo "PlaneFence Tweet error. Twitter returned:\n$(tail -1 /tmp/tweets.log)"
|
||||
rm -f $snapfile
|
||||
|
||||
else
|
||||
@@ -466,7 +436,7 @@ then
|
||||
fi
|
||||
|
||||
# Add a reference to the tweet to RECORD[7] (if no audio is available) or RECORD[11] (if audio is available)
|
||||
(( RECORD[7] < 0 )) && RECORD[12]="$LINK" || RECORD[7]="$LINK"
|
||||
if [[ -z "${RECORD[7]}" ]] && [[ -n "$LINK" ]]; then RECORD[12]="$LINK"; else RECORD[7]="$LINK"; fi
|
||||
# LOG "Tweet sent!"
|
||||
LOG "TWURL results: $LINK"
|
||||
else
|
||||
@@ -474,10 +444,16 @@ then
|
||||
fi
|
||||
|
||||
# Now write everything back to $CSVTMP
|
||||
( IFS=','; echo "${RECORD[*]}" >> "$CSVTMP" )
|
||||
LOG "The record now contains $(IFS=','; echo "${RECORD[*]}")"
|
||||
(
|
||||
IFS=','
|
||||
echo "${RECORD[*]}" >>"$CSVTMP"
|
||||
)
|
||||
LOG "The record now contains $(
|
||||
IFS=','
|
||||
echo "${RECORD[*]}"
|
||||
)"
|
||||
|
||||
done < "$CSVFILE"
|
||||
done <"$CSVFILE"
|
||||
# last, copy the TMP file back to the CSV file
|
||||
[ -f "$CSVTMP" ] && mv -f "$CSVTMP" "$CSVFILE"
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user