From d88371cd5dbe7b7103bad41942c520009ce4b69e Mon Sep 17 00:00:00 2001 From: EricClaeys <83164203+EricClaeys@users.noreply.github.com> Date: Wed, 29 Sep 2021 17:32:21 -0500 Subject: [PATCH 01/18] Implement centralized upload --- scripts/upload.sh | 136 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 scripts/upload.sh diff --git a/scripts/upload.sh b/scripts/upload.sh new file mode 100644 index 000000000..8a7109b99 --- /dev/null +++ b/scripts/upload.sh @@ -0,0 +1,136 @@ +#!/bin/bash + +# Script to upload files. +# This is a separate script so it can also be used manually to test uploads. +# Plus, this code was used in several other files and putting it here centralizes it. + +# Allow this script to be executed manually, which requires ALLSKY_HOME to be set. +if [ -z "${ALLSKY_HOME}" ] ; then + export ALLSKY_HOME="$(realpath $(dirname "${BASH_ARGV0}")/..)" +fi + +source "${ALLSKY_HOME}/variables.sh" +source "${ALLSKY_CONFIG}/config.sh" +source "${ALLSKY_SCRIPTS}/filename.sh" +source "${ALLSKY_SCRIPTS}/ftp-settings.sh" + +if [ "${1}" = "--silent" ] ; then + SILENT="true" + shift +else + SILENT="false" +fi + +ME="$(basename "${BASH_ARGV0}")" + +if [ $# -lt 3 ] ; then + # When run manually, the uniqueID (arg $4) normally won't be given. + echo -en "${RED}" + echo -n "*** Usage: ${ME} [--silent] file_to_upload directory destination_file_name" + echo -e "${NC}" + echo "Where:" + echo " '--silent' doesn't display any status messages" + echo " 'file_to_upload' is the path name of the file you want to upload." + echo " 'directory' is the directory ON THE SERVER the file should be uploaded to." + echo " 'destination_file_name' is the name the file should be called ON THE SERVER." + echo + echo -n "For example: ${ME} keogram-20210710.jgp /keograms keogram.jpg" + exit 1 +fi +FILE_TO_UPLOAD="${1}" +REMOTE_DIR="${2}" +DESTINATION_FILE="${3}" +if [ "${4}" = "" ] ; then + TEMP_NAME="x-${RANDOM}" +else + TEMP_NAME="${4}-${RANDOM}" +fi + +if [ ! -f "${FILE_TO_UPLOAD}" ] ; then + echo -en "${RED}" + echo -n "*** ${ME}: ERROR: File to upload '${FILE_TO_UPLOAD}' not found!" + echo -e "${NC}" + exit 2 +fi + + +# "put" to a temp name, then move the temp name to the final name. +# This is useful with slow uplinks where multiple lftp requests can be running at once, +# and only one lftp can upload the file at once, otherwise we get this error: +# put: Access failed: 550 The process cannot access the file because it is being used by +# another process. (image.jpg) +# Slow uplinks also cause problems with web servers that read the file as it's being uploaded. + +mkdir -p "${ALLSKY_TMP}" +LOG="${ALLSKY_TMP}/upload_log.txt" + +# Convert to lowercase so we don't care if user specified upper or lowercase. +PROTOCOL="${PROTOCOL,,}" + +if [[ "${PROTOCOL}" == "s3" ]] ; then + # xxxxxx How do you tell it the DESTINATION_FILE name ? + if [ "${SILENT}" = "false" -a "${ALLSKY_DEBUG_LEVEL}" -ge 3 ]; then + echo "${ME}: Uploading ${FILE_TO_UPLOAD} to aws ${S3_BUCKET}/${REMOTE_DIR}" + fi + ${AWS_CLI_DIR}/aws s3 cp "${FILE_TO_UPLOAD}" s3://${S3_BUCKET}${REMOTE_DIR} --acl ${S3_ACL} > "${LOG}" + +elif [[ ${PROTOCOL} == "local" ]] ; then + if [ "${SILENT}" = "false" -a "${ALLSKY_DEBUG_LEVEL}" -ge 3 ]; then + echo "${ME}: Copying ${FILE_TO_UPLOAD} to ${REMOTE_DIR}/${DESTINATION_FILE}" + fi + cp "${FILE_TO_UPLOAD}" "${REMOTE_DIR}/${DESTINATION_FILE}" + +else # sftp/ftp + # People sometimes have problems with ftp not working, + # so save the commands we use so they can run lftp manually to debug. + + # REMOTE_DIR can be ""; if so, don't add "/" + if [ "${REMOTE_DIR}" = "" ]; then + SLASH="" + else + SLASH="/" + fi + if [ "${SILENT}" = "false" -a "${ALLSKY_DEBUG_LEVEL}" -ge 3 ]; then + echo "${ME}: FTP'ing ${FILE_TO_UPLOAD} to ${REMOTE_DIR}${SLASH}${DESTINATION_FILE}" + fi + LFTP_CMDS="${ALLSKY_TMP}/lftp_cmds.txt" + + ( + [ "${LFTP_COMMANDS}" != "" ] && echo ${LFTP_COMMANDS} + # xxx TODO: escape double quotes in PASSWORD - how? With \ ? + P="${PASSWORD}" + echo open --user "\"${USER}\"" --password "\"${P}\"" "${PROTOCOL}://${HOST}" + # Sometimes have problems with "max-reties 1", so make it 2 + echo set net:max-retries 2 + echo set net:timeout 20 + echo rm -f ${TEMP_NAME} # just in case it's already there + echo put "\"${FILE_TO_UPLOAD}\"" -o ${TEMP_NAME} + echo rm -f "\"${DESTINATION_FILE}\"" + echo mv ${TEMP_NAME} "\"${REMOTE_DIR}${SLASH}${DESTINATION_FILE}\"" + echo bye + ) > "${LFTP_CMDS}" + lftp -f "${LFTP_CMDS}" > "${LOG}" 2>&1 + RET=$? + + if [ ${RET} -ne 0 ] ; then + echo -en "${RED}" + echo "*** ${ME}: ERROR:" + echo "FILE_TO_UPLOAD='${FILE_TO_UPLOAD}'" + echo "REMOTE_DIR='${REMOTE_DIR}'" + echo "TEMP_NAME='${TEMP_NAME}'" + echo "DESTINATION_FILE='${DESTINATION_FILE}'" + echo -en "${NC}" + echo + cat "${LOG}" + + echo -e "\n${YELLOW}Commands used${NC} (run via: ${GREEN}lftp -f ${LFTP_CMDS}${NC}):" + cat "${LFTP_CMDS}" + + elif tty --silent && [ "${SILENT}" = "false" ]; then + echo -en "${YELLOW}" + echo -n "INFO: '${LFTP_CMDS}' contains the lftp commands used to upload the file." + echo -e "${NC}" + fi +fi + +exit ${RET} From 6fa7b39f8971d8b31621044335d49b9593daab57 Mon Sep 17 00:00:00 2001 From: EricClaeys <83164203+EricClaeys@users.noreply.github.com> Date: Wed, 29 Sep 2021 18:05:24 -0500 Subject: [PATCH 02/18] Centralized Upload --- scripts/copy_notification_image.sh | 99 ++++++++++++++---------------- 1 file changed, 46 insertions(+), 53 deletions(-) diff --git a/scripts/copy_notification_image.sh b/scripts/copy_notification_image.sh index e7b87ba3a..01bd8dda7 100755 --- a/scripts/copy_notification_image.sh +++ b/scripts/copy_notification_image.sh @@ -1,85 +1,78 @@ #!/bin/bash -ME="$(basename "$BASH_ARGV0")" # Include script name in output so it's easier to find in the log file +ME="$(basename "${BASH_ARGV0}")" NOTIFICATIONFILE="$1" # filename, minus the extension, since the extension may vary if [ "$1" = "" ] ; then - echo "*** $ME: ERROR: no file specified" >&2 + echo "*** ${ME}: ERROR: no file specified" >&2 exit 1 fi -source $ALLSKY_HOME/config.sh -source $ALLSKY_HOME/scripts/filename.sh -source $ALLSKY_HOME/scripts/ftp-settings.sh +source "${ALLSKY_HOME}/variables.sh" +source "${ALLSKY_CONFIG}/config.sh" +source "${ALLSKY_SCRIPTS}/filename.sh" +source "${ALLSKY_SCRIPTS}/ftp-settings.sh" -cd $ALLSKY_HOME +cd "${ALLSKY_HOME}" -NOTIFICATIONFILE="notification_images/$NOTIFICATIONFILE.$EXTENSION" -if [ ! -e "$NOTIFICATIONFILE" ] ; then - echo "*** $ME: ERROR: File '$NOTIFICATIONFILE' does not exist or is empty!" >&2 - exit 1 +NOTIFICATIONFILE="${ALLSKY_NOTIFICATION_IMAGES}/${NOTIFICATIONFILE}.${EXTENSION}" +if [ ! -e "${NOTIFICATIONFILE}" ] ; then + echo "*** ${ME}: ERROR: File '${NOTIFICATIONFILE}' does not exist or is empty!" >&2 + exit 2 fi -IMAGE_TO_USE="$FULL_FILENAME" -cp "$NOTIFICATIONFILE" "$IMAGE_TO_USE" # don't overwrite notification image +IMAGE_TO_USE="${ALLSKY_TMP}/notification-${FULL_FILENAME}" +# Don't overwrite notification image so create a temporary copy and use that. +cp "${NOTIFICATIONFILE}" "${IMAGE_TO_USE}" # Resize the image if required -if [ $IMG_RESIZE = "true" ]; then - convert "$IMAGE_TO_USE" -resize "$IMG_WIDTH"x"$IMG_HEIGHT" "$IMAGE_TO_USE" +if [ "${IMG_RESIZE}" = "true" ]; then + convert "${IMAGE_TO_USE}" -resize "${IMG_WIDTH}x${IMG_HEIGHT}" "${IMAGE_TO_USE}" RET=$? - if [ $RET -ne 0 ] ; then - echo "*** $ME: ERROR: IMG_RESIZE failed with RET=$RET" - exit 1 + if [ ${RET} -ne 0 ] ; then + echo "*** ${ME}: ERROR: IMG_RESIZE failed with RET=${RET}" + exit 3 fi fi -# IMG_DIR and IMG_PREFIX are in config.sh -# If the user specified an IMG_PREFIX, copy the file to that name so the websites can display it. -if [ "${IMG_PREFIX}" != "" ]; then - cp "$IMAGE_TO_USE" "${IMG_PREFIX}${FILENAME}.${EXTENSION}" -fi - -# If 24 hour saving is desired, save the image in today's thumbnail directory +# If daytime saving is desired, save the image in today's thumbnail directory # so the user can see when things changed. # Don't save in main image directory because we don't want the notification image in timelapses. -if [ "$CAPTURE_24HR" = "true" ] ; then - CURRENT=$(date +'%Y%m%d') - mkdir -p images/$CURRENT - THUMBNAILS_DIR=images/$CURRENT/thumbnails - mkdir -p $THUMBNAILS_DIR +# If at nighttime, save them in (possibly) yesterday's directory. +# If during day, save in today's directory. +if [ "${CAPTURE_24HR}" = "true" ] ; then + IMAGES_DIR="${ALLSKY_IMAGES}/$(date -d '12 hours ago' +'%Y%m%d')" + [ ! -d "${IMAGES_DIR}" ] && IMAGES_DIR="${ALLSKY_IMAGES}/$(date +'%Y%m%d')" + THUMB="${IMAGES_DIR}/thumbnails/${FILENAME}-$(date +'%Y%m%d%H%M%S').${EXTENSION}" - SAVED_FILE="$FILENAME-$(date +'%Y%m%d%H%M%S').$EXTENSION" - # Create a thumbnail of the image for faster load in web GUI - convert "$IMAGE_TO_USE" -resize "${THUMBNAIL_SIZE_X}x${THUMBNAIL_SIZE_Y}" "$THUMBNAILS_DIR/$SAVED_FILE" + convert "${IMAGE_TO_USE}" -resize "${THUMBNAIL_SIZE_X}x${THUMBNAIL_SIZE_Y}" "${THUMB}" RET=$? - if [ $RET -ne 0 ] ; then - echo "*** $ME: WARNING: THUMBNAIL resize failed with RET=$RET; continuing." + if [ ${RET} -ne 0 ] ; then + echo "*** ${ME}: WARNING: THUMBNAIL resize failed with RET=${RET}; continuing." fi fi +mv -f "${IMAGE_TO_USE}" "${ALLSKY_HOME}/${FULL_FILENAME}" # so web severs can see it. + # If upload is true, optionally create a smaller version of the image and upload it -if [ "$UPLOAD_IMG" = "true" ] ; then - if [ "$RESIZE_UPLOADS" = "true" ]; then - echo -e "$ME: Resizing $NOTIFICATIONFILE for uploading" +if [ "${UPLOAD_IMG}" = "true" ] ; then + # Don't overwrite FULL_FILENAME since the web server(s) may be looking at it. + cp "${ALLSKY_HOME}/${FULL_FILENAME}" "${ALLSKY_TMP}" + IMAGE_TO_USE="${ALLSKY_TMP}/${FULL_FILENAME}" + if [ "${RESIZE_UPLOADS}" = "true" ]; then # Create a smaller version for upload - convert "$IMAGE_TO_USE" -resize "$RESIZE_UPLOADS_SIZE" -gravity East -chop 2x0 "$IMAGE_TO_USE" + convert "${IMAGE_TO_USE}" -resize "${RESIZE_UPLOADS_SIZE}" -gravity East -chop 2x0 "${IMAGE_TO_USE}" RET=$? - if [ $RET -ne 0 ] ; then - echo "*** $ME: ERROR: RESIZE_UPLOADS failed with RET=$RET" - exit 1 + if [ ${RET} -ne 0 ] ; then + echo "*** ${ME}: ERROR: RESIZE_UPLOADS failed with RET=${RET}" + exit 4 fi fi - TS=$(ls -l --time-style='+%H:%M:%S' $IMAGE_TO_USE | awk '{print $6}') - echo -e "$ME: Uploading $(basename $NOTIFICATIONFILE) with timestamp: $TS\n" - if [ $PROTOCOL = "S3" ] ; then - $AWS_CLI_DIR/aws s3 cp "$IMAGE_TO_USE" s3://$S3_BUCKET$IMGDIR --acl $S3_ACL & - elif [ $PROTOCOL = "local" ] ; then - cp "$IMAGE_TO_USE" "$IMGDIR" & - else - TEMP_NAME="ni-$RANDOM" - # "ni" = notification image. Use unique temporary name. - lftp "$PROTOCOL://$USER:$PASSWORD@$HOST:$IMGDIR" -e "set net:max-retries 2; set net:timeout 20; put "$IMAGE_TO_USE" -o $TEMP_NAME; rm -f "$IMAGE_TO_USE"; mv $TEMP_NAME "$IMAGE_TO_USE"; bye" & - - fi + # We're actually uploading $IMAGE_TO_USE, but show $NOTIFICATIONFILE + # in the message since it's more descriptive. + echo -e "${ME}: Uploading $(basename "${NOTIFICATIONFILE}")\n" + # NI == Notification Image + "${ALLSKY_SCRIPTS}/upload.sh" --silent "${IMAGE_TO_USE}" "${IMG_DIR}" "${FULL_FILENAME}" "NI" fi +exit 0 From 66e3e57e473754960bb3889b198200fffecfe528 Mon Sep 17 00:00:00 2001 From: EricClaeys <83164203+EricClaeys@users.noreply.github.com> Date: Wed, 29 Sep 2021 18:15:54 -0500 Subject: [PATCH 03/18] Centralized upload --- scripts/endOfNight.sh | 204 ++++++++++++++++++++++++------------------ 1 file changed, 115 insertions(+), 89 deletions(-) diff --git a/scripts/endOfNight.sh b/scripts/endOfNight.sh index 4c6fc0f65..58ca7dca3 100755 --- a/scripts/endOfNight.sh +++ b/scripts/endOfNight.sh @@ -1,115 +1,141 @@ #!/bin/bash +ME="$(basename "${BASH_ARGV0}")" + if [ $# -eq 1 ] ; then - if [ "x$1" = "x-h" ] ; then - echo "Usage: $BASH_ARGV0 [YYYYmmdd]" - exit - else - LAST_NIGHT=$1 - fi + if [ "${1}" = "-h" -o "${1}" = "--help" ] ; then + echo -e "${RED}Usage: ${ME} [YYYYmmdd]${NC}" + exit 0 + else + DATE="${1}" + fi else - LAST_NIGHT=$(date -d '12 hours ago' +'%Y%m%d') + DATE=$(date -d '12 hours ago' +'%Y%m%d') fi -source $ALLSKY_HOME/config.sh -source $ALLSKY_HOME/scripts/filename.sh -source $ALLSKY_HOME/scripts/ftp-settings.sh +# Allow this script to be executed manually, which requires several variables to be set. +if [ -z "$ALLSKY_HOME" ] ; then + export ALLSKY_HOME=$(realpath $(dirname "${BASH_ARGV0}")/..) +fi -cd $ALLSKY_HOME/scripts -ME="$(basename "$BASH_ARGV0")" # Include script name in output so it's easier to find in the log file +source "${ALLSKY_HOME}/variables.sh" +source "${ALLSKY_CONFIG}/config.sh" +source "${ALLSKY_SCRIPTS}/filename.sh" +source "${ALLSKY_SCRIPTS}/ftp-settings.sh" -# Post end of night data. This includes next twilight time -if [[ $POST_END_OF_NIGHT_DATA == "true" ]]; then - echo -e "$ME: Posting next twilight time to let server know when to resume liveview\n" - ./postData.sh - echo -e "\n" +DATE_DIR="${ALLSKY_IMAGES}/${DATE}" +if [ ! -d "${DATE_DIR}" ] ; then + echo -e "${ME}: ${RED}ERROR: '${DATE_DIR}' not found!${NC}" + exit 2 fi -LAST_NIGHT_DIR="$ALLSKY_HOME/images/$LAST_NIGHT" - -# Scan for, and remove corrupt images before generating -# keograms and startrails. This can take several (tens of) minutes to run -# and isn't necessary unless your system produces corrupt images which then -# generate funny colors in the summary images... -if [[ "$REMOVE_BAD_IMAGES" == "true" ]]; then - echo -e "$ME: Removing bad images\n" - ./removeBadImages.sh $LAST_NIGHT_DIR +# Post end of night data. This includes next twilight time +if [[ ${POST_END_OF_NIGHT_DATA} == "true" ]]; then + echo -e "${ME}: Posting next twilight time to let server know when to resume liveview\n" + "${ALLSKY_SCRIPTS}/postData.sh" + echo -e "\n" fi -TMP_DIR="$ALLSKY_HOME/tmp" -mkdir -p "$TMP_DIR" +# Remove corrupt images before generating keograms and startrails. +# This can take several (tens of) minutes to run and isn't necessary unless the system +# produces corrupt images which then generate funny colors in the summary images. +if [[ "${REMOVE_BAD_IMAGES}" == "true" ]]; then + echo -e "${ME}: ===== Removing bad images" + "${ALLSKY_SCRIPTS}/removeBadImages.sh" "${DATE_DIR}" + echo +fi # Generate keogram from collected images -if [[ $KEOGRAM == "true" ]]; then - echo -e "$ME: Generating Keogram\n" - mkdir -p $LAST_NIGHT_DIR/keogram/ - OUTPUT="$LAST_NIGHT_DIR/keogram/keogram-$LAST_NIGHT.$EXTENSION" - ${ALLSKY_HOME}/keogram -d $LAST_NIGHT_DIR/ -e $EXTENSION -o $OUTPUT - RETCODE=$? - if [[ $UPLOAD_KEOGRAM == "true" && $RETCODE = 0 ]] ; then - if [[ $PROTOCOL == "S3" ]] ; then - $AWS_CLI_DIR/aws s3 cp $OUTPUT s3://$S3_BUCKET$KEOGRAM_DIR --acl $S3_ACL & - elif [[ $PROTOCOL == "local" ]] ; then - cp $OUTPUT $KEOGRAM_DIR & - else - lftp "$PROTOCOL://$USER:$PASSWORD@$HOST:$KEOGRAM_DIR" \ - -e "set net:max-retries 1; put "$OUTPUT"; bye" & - fi - fi - - # Optionally copy to the local website in addition to the upload above. - if [ "$WEB_KEOGRAM_DIR" != "" ]; then - cp $OUTPUT "$WEB_KEOGRAM_DIR" - fi +if [[ ${KEOGRAM} == "true" ]]; then + echo -e "${ME}: ===== Generating Keogram" + mkdir -p "${DATE_DIR}/keogram/" + KEOGRAM_FILE="keogram-${DATE}.${EXTENSION}" + UPLOAD_FILE="${DATE_DIR}/keogram/${KEOGRAM_FILE}" + + "${ALLSKY_HOME}/keogram" -d "${DATE_DIR}/" -e ${EXTENSION} -o "${UPLOAD_FILE}" ${KEOGRAM_PARAMETERS} + RETCODE=$? + if [[ ${UPLOAD_KEOGRAM} == "true" && ${RETCODE} = 0 ]] ; then + # If the user specified a different name for the destination file, use it. + if [ "${KEOGRAM_DESTINATION_NAME}" != "" ]; then + KEOGRAM_FILE="${KEOGRAM_DESTINATION_NAME}" + fi + # KG == KeoGram + "${ALLSKY_SCRIPTS}/upload.sh" "${UPLOAD_FILE}" "${KEOGRAM_DIR}" "${KEOGRAM_FILE}" "KG" + + # Optionally copy to the local website in addition to the upload above. + if [ "${WEB_KEOGRAM_DIR}" != "" ]; then + echo "${ME}: Copying ${UPLOAD_FILE} to ${WEB_KEOGRAM_DIR}" + cp ${UPLOAD_FILE} "${WEB_KEOGRAM_DIR}" + fi + fi + echo fi # Generate startrails from collected images. # Threshold set to 0.1 by default in config.sh to avoid stacking over-exposed images. -if [[ $STARTRAILS == "true" ]]; then - echo -e "$ME: Generating Startrails\n" - mkdir -p $LAST_NIGHT_DIR/startrails/ - OUTPUT="$LAST_NIGHT_DIR/startrails/startrails-$LAST_NIGHT.$EXTENSION" - # The startrails command outputs one line for each of the many hundreds of files, - # and this adds needless clutter to the log file, so send output to a tmp file so we can output the - # number of images. - ${ALLSKY_HOME}/startrails -d $LAST_NIGHT_DIR/ -e $EXTENSION -b $BRIGHTNESS_THRESHOLD -o $OUTPUT - RETCODE=$? - if [[ $UPLOAD_STARTRAILS == "true" && $RETCODE == 0 ]] ; then - if [[ $PROTOCOL == "S3" ]] ; then - $AWS_CLI_DIR/aws s3 cp $OUTPUT s3://$S3_BUCKET$STARTRAILS_DIR --acl $S3_ACL & - elif [[ $PROTOCOL == "local" ]] ; then - cp $OUTPUT $STARTRAILS_DIR & - else - lftp "$PROTOCOL"://"$USER":"$PASSWORD"@"$HOST":"$STARTRAILS_DIR" \ - -e "set net:max-retries 1; put $OUTPUT; bye" & - fi - fi - - # Optionally copy to the local website in addition to the upload above. - if [ "$WEB_STARTRAILS_DIR" != "" ]; then - cp $OUTPUT "$WEB_STARTRAILS_DIR" - fi +if [[ ${STARTRAILS} == "true" ]]; then + echo -e "${ME}: ===== Generating Startrails" + mkdir -p ${DATE_DIR}/startrails/ + STARTRAILS_FILE="startrails-${DATE}.${EXTENSION}" + UPLOAD_FILE="${DATE_DIR}/startrails/${STARTRAILS_FILE}" + + "${ALLSKY_HOME}/startrails" "${DATE_DIR}/" ${EXTENSION} ${BRIGHTNESS_THRESHOLD} "${UPLOAD_FILE}" + RETCODE=$? + if [[ ${UPLOAD_STARTRAILS} == "true" && ${RETCODE} == 0 ]] ; then + # If the user specified a different name for the destination file, use it. + if [ "${STARTRAILS_DESTINATION_NAME}" != "" ]; then + STARTRAILS_FILE="${STARTRAILS_DESTINATION_NAME}" + fi + # ST == Star Trails + "${ALLSKY_SCRIPTS}/upload.sh" "${UPLOAD_FILE}" "${STARTRAILS_DIR}" "${STARTRAILS_FILE}" "ST" + + # Optionally copy to the local website in addition to the upload above. + if [ "${WEB_STARTRAILS_DIR}" != "" ]; then + echo "${ME}: Copying ${UPLOAD_FILE} to ${WEB_STARTRAILS_DIR}" + cp "${UPLOAD_FILE}" "${WEB_STARTRAILS_DIR}" + fi + fi + echo fi -# Generate timelapse from collected images -if [[ $TIMELAPSE == "true" ]]; then - echo -e "$ME: Generating Timelapse\n" - ./timelapse.sh $LAST_NIGHT - echo -e "\n" +# Generate timelapse from collected images. +# Use timelapse.sh instead of putting all the commands here so users can easily +# test the timelapse creation, which sometimes has issues. +if [[ ${TIMELAPSE} == "true" ]]; then + echo -e "${ME}: ===== Generating Timelapse" + "${ALLSKY_SCRIPTS}/timelapse.sh" "${DATE}" + RETCODE=$? + if [[ ${UPLOAD_VIDEO} == "true" && ${RETCODE} == 0 ]] ; then + VIDEOS_FILE="allsky-${DATE}.mp4" + UPLOAD_FILE="${DATE_DIR}/${VIDEOS_FILE}" + # If the user specified a different name for the destination file, use it. + if [ "${VIDEOS_DESTINATION_NAME}" != "" ]; then + VIDEOS_FILE="${VIDEOS_DESTINATION_NAME}" + fi + # TL == Time Lapse + "${ALLSKY_SCRIPTS}/upload.sh" "${UPLOAD_FILE}" "${VIDEOS_DIR}" "${VIDEOS_FILE}" "TL" - # Optionally copy to the local website in addition to the upload above. - if [ "$WEB_MP4DIR" != "" ]; then - cp $LAST_NIGHT_DIR/allsky-$LAST_NIGHT.mp4 "$WEB_MP4DIR" - fi + # Optionally copy to the local website in addition to the upload above. + if [ "${WEB_VIDEOS_DIR}" != "" ]; then + TIMELAPSE_FILE="allsky-${DATE}.mp4" + UPLOAD_FILE="${DATE_DIR}/${TIMELAPSE_FILE}" + echo "${ME}: Copying ${UPLOAD_FILE} to ${WEB_VIDEOS_DIR}" + cp "${UPLOAD_FILE}" "${WEB_VIDEOS_DIR}" + fi + fi + # timelapse.sh handled ${TMP} fi -# Run custom script at the end of a night. This is run BEFORE the automatic deletion just in case you need to do something with the files before they are removed -./endOfNight_additionalSteps.sh +# Run custom script at the end of a night. This is run BEFORE the automatic deletion +# just in case you need to do something with the files before they are removed +"${ALLSKY_SCRIPTS}/endOfNight_additionalSteps.sh" # Automatically delete old images and videos -if [[ $AUTO_DELETE == "true" ]]; then - del=$(date --date="$NIGHTS_TO_KEEP days ago" +%Y%m%d) - for i in `find $ALLSKY_HOME/images/ -type d -name "2*"`; do # "2*" for years >= 2000 - (($del > $(basename $i))) && rm -rf $i - done +if [[ ${AUTO_DELETE} == "true" ]]; then + del=$(date --date="${NIGHTS_TO_KEEP} days ago" +%Y%m%d) + for i in $(find "${ALLSKY_IMAGES}/" -type d -name "2*"); do # "2*" for years >= 2000 + ((${del} > $(basename ${i}))) && echo "Deleting old directory ${i}" && rm -rf ${i} + done fi + +exit 0 From ccd5d0c0ea96566c33f89039cf70521bb743f87b Mon Sep 17 00:00:00 2001 From: EricClaeys <83164203+EricClaeys@users.noreply.github.com> Date: Wed, 29 Sep 2021 18:18:06 -0500 Subject: [PATCH 04/18] Centralized upload --- scripts/postData.sh | 46 +++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/scripts/postData.sh b/scripts/postData.sh index 53548de13..6c6365028 100755 --- a/scripts/postData.sh +++ b/scripts/postData.sh @@ -1,33 +1,35 @@ #!/bin/bash -source $ALLSKY_HOME/config.sh -source $ALLSKY_HOME/scripts/ftp-settings.sh # TODO Needs fixing when civil twilight happens after midnight -cd $ALLSKY_HOME/scripts -ME="$(basename "$BASH_ARGV0")" # Include script name in output so it's easier to find in the log file -latitude=$(jq -r '.latitude' "$CAMERA_SETTINGS") -longitude=$(jq -r '.longitude' "$CAMERA_SETTINGS") +source "${ALLSKY_HOME}/variables.sh" +source "${ALLSKY_CONFIG}/config.sh" +source "${ALLSKY_SCRIPTS}/ftp-settings.sh" + +ME="$(basename "${BASH_ARGV0}")" + +latitude=$(jq -r '.latitude' "${CAMERA_SETTINGS}") +longitude=$(jq -r '.longitude' "${CAMERA_SETTINGS}") timezone=-0700 streamDaytime=false -if [[ $DAYTIME == "1" ]] ; then - streamDaytime=true; +if [[ ${DAYTIME} == "true" || ${DAYTIME} == "1" ]] ; then + streamDaytime="true" fi -#echo "$ME: Posting Next Twilight Time" +echo "${ME}: Posting Next Twilight Time" today=`date +%Y-%m-%d` -time="$(sunwait list set civil $latitude $longitude)" +time="$(sunwait list set civil ${latitude} ${longitude})" timeNoZone=${time:0:5} -echo { > data.json -echo \"sunset\": \"$today"T"$timeNoZone":00.000$timezone"\", >> data.json -echo \"streamDaytime\": \"$streamDaytime\" >> data.json -echo } >> data.json -echo "$ME: Uploading data.json" -if [[ $PROTOCOL == "S3" ]] ; then - $AWS_CLI_DIR/aws s3 cp data.json s3://$S3_BUCKET$IMGDIR --acl $S3_ACL & -elif [[ $PROTOCOL == "local" ]] ; then - cp data.json $IMGDIR & -else - lftp "$PROTOCOL://$USER:$PASSWORD@$HOST:$IMGDIR" -e "set net:max-retries 1; set net:timeout 20; put data.json; bye" & -fi + +FILE="data.json" +OUTPUT_FILE="${ALLSKY_TMP}/${FILE}" +( + echo { + echo \"sunset\": \"$today"T"$timeNoZone":00.000$timezone"\", + echo \"streamDaytime\": \"$streamDaytime\" + echo } +) > "${OUTPUT_FILE}" + +# PD == Post Data +"${ALLSKY_SCRIPTS}/upload.sh" --silent "${OUTPUT_FILE}" "${IMG_DIR}" "${FILE}" "PD" From 57be9e5fa5c06f8be011a8eadf72edc54eeda8a1 Mon Sep 17 00:00:00 2001 From: EricClaeys <83164203+EricClaeys@users.noreply.github.com> Date: Wed, 29 Sep 2021 18:46:25 -0500 Subject: [PATCH 05/18] Centralized upload --- scripts/saveImageDay.sh | 67 +++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 42 deletions(-) diff --git a/scripts/saveImageDay.sh b/scripts/saveImageDay.sh index 051e54b8a..e90f49ae3 100755 --- a/scripts/saveImageDay.sh +++ b/scripts/saveImageDay.sh @@ -1,21 +1,24 @@ #!/bin/bash -source $ALLSKY_HOME/config.sh -source $ALLSKY_HOME/scripts/filename.sh -source $ALLSKY_HOME/scripts/darkCapture.sh # does not return if in darkframe mode -source $ALLSKY_HOME/scripts/ftp-settings.sh + +ME="$(basename "$BASH_ARGV0")" + +source "${ALLSKY_HOME}/variables.sh" +source "${ALLSKY_CONFIG}/config.sh" +source "${ALLSKY_SCRIPTS}/filename.sh" +source "${ALLSKY_SCRIPTS}/darkCapture.sh" # does not return if in darkframe mode +source "${ALLSKY_SCRIPTS}/ftp-settings.sh" cd $ALLSKY_HOME -ME="$(basename "$BASH_ARGV0")" # Include script name in output so it's easier to find in the log file IMAGE_TO_USE="$FULL_FILENAME" # quotes around $IMAGE_TO_USE below, in case it has a space or special characters. -# Make sure the image isn't corrupted +# Quick check to make sure the image isn't corrupted. identify "$IMAGE_TO_USE" >/dev/null 2>&1 RET=$? if [ $RET -ne 0 ] ; then - echo "*** $ME: ERROR: Image '${IMAGE_TO_USE} is corrupt; ignoring." - exit 1 + echo "${RED}*** $ME: ERROR: Image '${IMAGE_TO_USE} is corrupt; ignoring.${NC}" + exit 3 fi # Resize the image if required @@ -23,8 +26,8 @@ if [[ $IMG_RESIZE == "true" ]]; then convert "$IMAGE_TO_USE" -resize "$IMG_WIDTH"x"$IMG_HEIGHT" "$IMAGE_TO_USE" RET=$? if [ $RET -ne 0 ] ; then - echo "*** $ME: ERROR: IMG_RESIZE failed with RET=$RET" - exit 1 + echo "${RED}*** $ME: ERROR: IMG_RESIZE failed with RET=$RET${NC}" + exit 4 fi fi @@ -33,8 +36,8 @@ if [[ $CROP_IMAGE == "true" ]]; then convert "$IMAGE_TO_USE" -gravity Center -crop "$CROP_WIDTH"x"$CROP_HEIGHT"+"$CROP_OFFSET_X"+"$CROP_OFFSET_Y" +repage "$IMAGE_TO_USE" RET=$? if [ $RET -ne 0 ] ; then - echo "*** $ME: ERROR: CROP_IMAGE failed with RET=$RET" - exit 1 + echo "${RED}*** $ME: ERROR: CROP_IMAGE failed with RET=$RET${NC}" + exit 4 fi fi @@ -44,17 +47,16 @@ if [ "${IMG_PREFIX}" != "" ]; then cp "$IMAGE_TO_USE" "${IMG_PREFIX}${FILENAME}.${EXTENSION}" fi -# If 24 hour saving is desired, save the current image in today's directory -if [ "$CAPTURE_24HR" = "true" ] ; then - CURRENT=$(date +'%Y%m%d') +# If daytime saving is desired, save the current image in today's directory +if [ "${CAPTURE_24HR}" = "true" -o "${DAYTIME_SAVE}" = "true" ] ; then + DATE_DIR="${ALLSKY_IMAGES}/$(date +'%Y%m%d')" - mkdir -p images/$CURRENT - THUMBNAILS_DIR=images/$CURRENT/thumbnails - mkdir -p $THUMBNAILS_DIR + THUMBNAILS_DIR=${DATE_DIR}/thumbnails + mkdir -p $THUMBNAILS_DIR # it also makes ${DATE_DIR} - # Save image in images/current directory + # Copy image to the final location. SAVED_FILE="$FILENAME-$(date +'%Y%m%d%H%M%S').$EXTENSION" - cp "$IMAGE_TO_USE" "images/$CURRENT/$SAVED_FILE" + cp "$IMAGE_TO_USE" "${DATE_DIR}/${SAVED_FILE}" # Create a thumbnail of the image for faster load in web GUI. # If we resized above, this will be a resize of a resize, @@ -69,33 +71,14 @@ fi # If upload is true, optionally create a smaller version of the image; either way, upload it if [ "$UPLOAD_IMG" = true ] ; then if [[ "$RESIZE_UPLOADS" == "true" ]]; then - echo -e "$ME: Resizing '$IMAGE_TO_USE' for uploading" - echo -e "$ME: Resizing '$IMAGE_TO_USE' for uploading\n" >> log.txt - # Create a smaller version for upload convert "$IMAGE_TO_USE" -resize "$RESIZE_UPLOADS_SIZE" -gravity East -chop 2x0 "$IMAGE_TO_USE" RET=$? if [ $RET -ne 0 ] ; then - echo "*** $ME: ERROR: RESIZE_UPLOADS failed with RET=$RET" - exit 1 + echo -e "${YELLOW}*** ${ME}: WARNING: RESIZE_UPLOADS failed with RET=${RET}; continuing with larger image.${NC}" fi fi - TS=$(ls -l --time-style='+%H:%M:%S' "$IMAGE_TO_USE" | awk '{print $6}') - echo -e "$ME: Uploading '$IMAGE_TO_USE' with timestamp: $TS\n" - echo -e "$ME: Uploading '$IMAGE_TO_USE' with timestamp: $TS" >> log.txt - if [[ $PROTOCOL == "S3" ]] ; then - $AWS_CLI_DIR/aws s3 cp "$IMAGE_TO_USE" s3://$S3_BUCKET$IMGDIR --acl $S3_ACL & - elif [[ $PROTOCOL == "local" ]] ; then - cp "$IMAGE_TO_USE" "$IMGDIR" & - else - # Put to a temp name, then move the temp name to the final name. - # This is because slow uplinks can cause multiple lftp requests to be running at once, - # and only one lftp can upload the file at once, otherwise get this error: - # put: Access failed: 550 The process cannot access the file because it is being used by another process. (image.jpg) - # Slow uploads also cause a problem with web pages that try to read the file as it's being uploaded. - # "si" = "save image" - use a unique temporary name - TEMP_NAME="si-$RANDOM" - lftp "$PROTOCOL://$USER:$PASSWORD@$HOST:$IMGDIR" -e "set net:max-retries 2; set net:timeout 20; put "$IMAGE_TO_USE" -o $TEMP_NAME; rm -f "$IMAGE_TO_USE"; mv $TEMP_NAME "$IMAGE_TO_USE"; bye" & - fi + "${ALLSKY_SCRIPTS}/upload.sh" "${IMAGE_TO_USE}" "${IMGDIR}" "${IMAGE_TO_USE}" "SI" fi +exit 0 From e6c3b2ee1fb3e1945c260ec52a67e4288850be7f Mon Sep 17 00:00:00 2001 From: EricClaeys <83164203+EricClaeys@users.noreply.github.com> Date: Wed, 29 Sep 2021 19:04:34 -0500 Subject: [PATCH 06/18] Centralized upload --- scripts/saveImageNight.sh | 89 +++++++++++++++------------------------ 1 file changed, 33 insertions(+), 56 deletions(-) diff --git a/scripts/saveImageNight.sh b/scripts/saveImageNight.sh index 2bc777163..50d5acacd 100755 --- a/scripts/saveImageNight.sh +++ b/scripts/saveImageNight.sh @@ -1,24 +1,27 @@ #!/bin/bash -source $ALLSKY_HOME/config.sh -source $ALLSKY_HOME/scripts/filename.sh -source $ALLSKY_HOME/scripts/darkCapture.sh # does not return if in darkframe mode -source $ALLSKY_HOME/scripts/darkSubtract.sh -source $ALLSKY_HOME/scripts/ftp-settings.sh + +ME="$(basename "${BASH_ARGV0}")" + +source "${ALLSKY_HOME}/variables.sh" +source "${ALLSKY_CONFIG}/config.sh" +source "${ALLSKY_SCRIPTS}/filename.sh" +source "${ALLSKY_SCRIPTS}/darkCapture.sh" # does not return if in darkframe mode +source "${ALLSKY_SCRIPTS}/darkSubtract.sh" +source "${ALLSKY_SCRIPTS}/ftp-settings.sh" cd $ALLSKY_HOME -ME="$(basename "$BASH_ARGV0")" # Include script name in output so it's easier to find in the log file # Make a directory to store current night images. -# The 12 hours ago option ensures that we're always using today's date even at high latitudes where civil twilight can start after midnight. -CURRENT=$(date -d '12 hours ago' +'%Y%m%d') -mkdir -p images/$CURRENT -THUMBNAILS_DIR=images/$CURRENT/thumbnails -mkdir -p $THUMBNAILS_DIR +# The 12 hours ago option ensures that we're always using today's date +# even at high latitudes where civil twilight can start after midnight. +DATE_DIR="${ALLSKY_IMAGES}/$(date -d '12 hours ago' +'%Y%m%d')" +THUMBNAILS_DIR="${DATE_DIR}/thumbnails" +mkdir -p ${THUMBNAILS_DIR} # it also makes ${DATE_DIR} # Create image to use (original or processed) for liveview in GUI IMAGE_TO_USE="$FULL_FILENAME" if [ "$IMAGE_TO_USE" = "" ]; then - echo "*** $ME: ERROR: IMAGE_TO_USE is null." + echo "${RED}*** $ME: ERROR: IMAGE_TO_USE is null.${NC}" exit 1 fi # quotes around $IMAGE_TO_USE below, in case it has a space or special characters. @@ -27,8 +30,8 @@ fi identify "$IMAGE_TO_USE" >/dev/null 2>&1 RET=$? if [ $RET -ne 0 ] ; then - echo "*** $ME: ERROR: Image '${IMAGE_TO_USE}' is corrupt; ignoring." - exit 1 + echo -e "${RED}*** ${ME}: ERROR: Image '${IMAGE_TO_USE}' is corrupt; ignoring.${NC}" + exit 3 fi if [ "$DARK_FRAME_SUBTRACTION" = "true" ] ; then @@ -36,7 +39,7 @@ if [ "$DARK_FRAME_SUBTRACTION" = "true" ] ; then PROCESSED_FILE="$FILENAME-processed.$EXTENSION" # Check in case the user has subtraction set to "true" but has no dark frames. if [[ ! -f "$PROCESSED_FILE" ]]; then - echo "*** $ME: WARNING: Processed image '$PROCESSED_FILE' does not exist; continuing!" >> log.txt + echo "${YELLOW}*** $ME: WARNING: Processed image '$PROCESSED_FILE' does not exist; continuing!${NC}" else # Want the name of the final file to alway be the same mv -f "$PROCESSED_FILE" "$IMAGE_TO_USE" @@ -48,8 +51,8 @@ if [[ $IMG_RESIZE == "true" ]]; then convert "$IMAGE_TO_USE" -resize "$IMG_WIDTH"x"$IMG_HEIGHT" "$IMAGE_TO_USE" RET=$? if [ $RET -ne 0 ] ; then - echo "*** $ME: ERROR: IMG_RESIZE failed with RET=$RET" - exit 1 + echo -e "${RED}*** ${ME}: ERROR: IMG_RESIZE failed with RET=${RET}{$NC}" + exit 4 fi fi @@ -58,8 +61,8 @@ if [[ $CROP_IMAGE == "true" ]]; then convert "$IMAGE_TO_USE" -gravity Center -crop "$CROP_WIDTH"x"$CROP_HEIGHT"+"$CROP_OFFSET_X"+"$CROP_OFFSET_Y" +repage "$IMAGE_TO_USE" RET=$? if [ $RET -ne 0 ] ; then - echo "*** $ME: ERROR: CROP_IMAGE failed with RET=$RET" - exit 1 + echo -e "${RED}*** ${ME}: ERROR: CROP_IMAGE failed with RET=${RET}{$NC}" + exit 4 fi fi @@ -68,8 +71,8 @@ if [[ $AUTO_STRETCH == "true" ]]; then convert "$IMAGE_TO_USE" -sigmoidal-contrast "$AUTO_STRETCH_AMOUNT","$AUTO_STRETCH_MID_POINT" "$IMAGE_TO_USE" RET=$? if [ $RET -ne 0 ] ; then - echo "*** $ME: ERROR: AUTO_STRETCH failed with RET=$RET" - exit 1 + echo -e "${RED}*** ${ME}: ERROR: AUTO_STRETCH failed with RET=${RET}${NC}" + exit 4 fi fi @@ -79,56 +82,30 @@ if [ "${IMG_PREFIX}" != "" ]; then cp "$IMAGE_TO_USE" "${IMG_PREFIX}${FILENAME}.${EXTENSION}" fi -# Save image in images/current directory +# Copy image to the final location. SAVED_FILE="$FILENAME-$(date +'%Y%m%d%H%M%S').$EXTENSION" -cp "$IMAGE_TO_USE" "images/$CURRENT/$SAVED_FILE" +cp "$IMAGE_TO_USE" "${DATE_DIR}/${SAVED_FILE}" # Create a thumbnail of the image for faster load in web GUI. # If we resized above, this will be a resize of a resize, but for thumbnails it should be ok. convert "$IMAGE_TO_USE" -resize "${THUMBNAIL_SIZE_X}x${THUMBNAIL_SIZE_Y}" "$THUMBNAILS_DIR/$SAVED_FILE" RET=$? if [ $RET -ne 0 ] ; then - echo "*** $ME: ERROR: THUMBNAIL resize failed with RET=$RET; continuing." + echo -e "${YELLOW}*** ${ME}: WARNING: THUMBNAIL resize failed with RET=${RET}; continuing.${NC}" fi # If upload is true, optionally create a smaller version of the image; either way, upload it if [[ "$UPLOAD_IMG" == "true" ]] ; then if [[ "$RESIZE_UPLOADS" == "true" ]]; then - echo -e "$ME: Resizing '$IMAGE_TO_USE' for uploading\n" - echo -e "$ME: Resizing '$IMAGE_TO_USE' for uploading\n" >> log.txt - # Create smaller version for upload convert "$IMAGE_TO_USE" -resize "$RESIZE_UPLOADS_SIZE" -gravity East -chop 2x0 "$IMAGE_TO_USE" RET=$? - [ $RET -ne 0 ] && echo "*** $ME: ERROR: RESIZE_UPLOADS failed with RET=$RET" + if [ ${RET} -ne 0 ] ; then + echo -e "${YELLOW}*** ${ME}: WARNING: RESIZE_UPLOADS failed with RET=${RET}; continuing with larger image.${NC}" + fi fi - TS=$(ls -l --time-style='+%H:%M:%S' $IMAGE_TO_USE | awk '{print $6}') - echo -e "$ME: Uploading '$IMAGE_TO_USE' with timestamp: $TS\n" - echo -e "$ME: Uploading '$IMAGE_TO_USE' with timestamp: $TS" >> log.txt - if [[ $PROTOCOL == "S3" ]] ; then - $AWS_CLI_DIR/aws s3 cp "$IMAGE_TO_USE" s3://$S3_BUCKET$IMGDIR --acl $S3_ACL & - elif [[ $PROTOCOL == "local" ]] ; then - cp "$IMAGE_TO_USE" "$IMGDIR" & - elif [[ $PROTOCOL == "test" ]]; then # added for testing - (echo set ssl:check-hostname false - echo open -u "$USER,$PASSWORD" "ftp://$HOST" - echo cd "$IMGDIR" - echo set net:max-retries 1 - echo set net:timeout 20 - echo put "$IMAGE_TO_USE" - echo bye - ) > night.lftp - lftp -d -f night.lftp > log_night.txt 2>&1 & - - else - # "put" to a temp name, then move the temp name to the final name. - # This is because slow uplinks can cause multiple lftp requests to be running at once, - # and only one lftp can upload the file at once, otherwise get this error: - # put: Access failed: 550 The process cannot access the file because it is being used by another process. (image.jpg) - # Slow uploads also cause a problem with web pages that try to read the file as it's being uploaded. - # "si" = "save image" - use a unique temporary name - TEMP_NAME="si-$RANDOM" - lftp "$PROTOCOL://$USER:$PASSWORD@$HOST:$IMGDIR" -e "set net:max-retries 2; set net:timeout 20; put "$IMAGE_TO_USE" -o $TEMP_NAME; rm -f "$IMAGE_TO_USE"; mv $TEMP_NAME "$IMAGE_TO_USE"; bye" & - fi + "${ALLSKY_SCRIPTS}/upload.sh" "${IMAGE_TO_USE}" "${IMGDIR}" "${IMAGE_TO_USE}" "SI" + exit $? fi +exit 0 From 343d6b5e79619bfa25705d6322c6aafc727a1317 Mon Sep 17 00:00:00 2001 From: EricClaeys <83164203+EricClaeys@users.noreply.github.com> Date: Wed, 29 Sep 2021 19:26:51 -0500 Subject: [PATCH 07/18] Centralized upload --- scripts/timelapse.sh | 149 ++++++++++++++++++------------------------- 1 file changed, 63 insertions(+), 86 deletions(-) diff --git a/scripts/timelapse.sh b/scripts/timelapse.sh index 381b606c8..71f6ce48f 100755 --- a/scripts/timelapse.sh +++ b/scripts/timelapse.sh @@ -1,45 +1,49 @@ #!/bin/bash -if [ -z "$ALLSKY_HOME" ] ; then - export ALLSKY_HOME=$(realpath $(dirname "$BASH_ARGV0")/..) +# Allow this script to be executed manually, which requires ALLSKY_HOME to be set. +if [ -z "${ALLSKY_HOME}" ] ; then + export ALLSKY_HOME="$(realpath $(dirname "${BASH_ARGV0}")/..)" fi -source $ALLSKY_HOME/config.sh -source $ALLSKY_HOME/scripts/filename.sh -source $ALLSKY_HOME/scripts/ftp-settings.sh +source "${ALLSKY_HOME}/variables.sh" +source "${ALLSKY_CONFIG}/config.sh" +source "${ALLSKY_SCRIPTS}/filename.sh" +source "${ALLSKY_SCRIPTS}/ftp-settings.sh" -cd $ALLSKY_HOME - -ME="$(basename "$BASH_ARGV0")" # Include script name in output so it's easier to find in the log file +ME="$(basename "${BASH_ARGV0}")" -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[0;33m' -NC='\033[0m' # No Color +cd $ALLSKY_HOME -if [ $# -lt 1 -o $# -gt 2 -o "x$1" = "x-h" ] ; then +if [ $# -lt 1 -o $# -gt 2 -o "${1}" = "-h" -o "${1}" = "--help" ] ; then TODAY=$(date +%Y%m%d) - echo -en "${RED}Usage: ${ME} [directory]${NC}\n" - echo -en " ex: timelapse.sh ${TODAY}\n" - echo -en " or: timelapse.sh ${TODAY} /media/external/allsky/${TODAY}\n" - exit 3 + echo -en "${RED}" + echo -n "Usage: ${ME} [--help] DATE [directory]" + echo -e "${NC}" + echo " example: ${ME} ${TODAY}" + echo " or: ${ME} ${TODAY} /media/external/allsky" + echo -en "${YELLOW}" + echo "'DATE' must be in '${ALLSKY_IMAGES}' unless 'directory' is specified," + echo "in which case 'DATE' must bin in 'directory', i.e., 'directory/DATE'." + echo -en "${NC}" + exit 1 fi -# Allow timelapses of pictures not in ALLSKY_HOME. -# If $2 is passed, it's the top folder, otherwise use the one in ALLSKY_HOME. -DAY="$1" -if [ "$2" = "" ] ; then - DIR="$ALLSKY_HOME/images/$DAY" # Need full pathname for links +# Allow timelapses of pictures not in the standard ALLSKY_IMAGES directory. +# If $2 is passed, it's the top folder, otherwise use the one in ALLSKY_IMAGES. +DATE="${1}" +if [ "${2}" = "" ] ; then + DATE_DIR="${ALLSKY_IMAGES}/${DATE}" # Need full pathname for links else - DIR="$2" + DATE_DIR="${2}/${DATE}" fi # Guess what the likely image extension is (unless specified in the config) by # looking at the most common extension in the target day directory -if [ -z "$EXTENSION" ] ; then - EXT_GUESS=$(ls $DIR | sed -e 's/.*[.]//' | sort | uniq -c | head -1 | sed -e 's/.* //') - echo -en "${RED}${ME}: file EXTENSION not found in configuration, guessing ${EXT_GUESS}${NC}\n" - EXTENSION=$EXT_GUESS +if [ -z "${EXTENSION}" ] ; then + EXTENSION=$(ls "${DATE_DIR}" | sed -e 's/.*[.]//' | sort | uniq -c | head -1 | sed -e 's/.* //') + echo -en "${YELLOW}" + echo -n "${ME}: file EXTENSION not found in configuration, guessing ${EXTENSION}" + echo -e "${NC}" fi # If you are tuning encoder settings, run this script with KEEP_SEQUENCE, eg. @@ -48,37 +52,36 @@ fi # of the sequence directory if it looks ok (contains at least 100 files). This # might save you some time when running your encoder repeatedly. -NSEQ=$(ls "/${DIR}/sequence" 2>/dev/null | wc -l ) +SEQUENCE_DIR="${DATE_DIR}/sequencce" +NSEQ=$(ls "${SEQUENCE_DIR}" 2>/dev/null | wc -l ) if [ -z "$KEEP_SEQUENCE" -o $NSEQ -lt 100 ] ; then - echo -en "${ME}: ${GREEN}Creating symlinks to generate timelapse${NC}\n" - rm -fr $DIR/sequence - mkdir -p $DIR/sequence - - # find images, make symlinks sequentially and start avconv to build mp4; upload mp4 and move directory - find "$DIR" -name "*.$EXTENSION" -size 0 -delete - - TMP_DIR="$ALLSKY_HOME/tmp" - mkdir -p "$TMP_DIR" - TMP="$TMP_DIR/timelapseTMP.txt" # capture the "ln" commands in case the user needs to debug - > $TMP - ls -rt $DIR/*.$EXTENSION | + rm -fr "${SEQUENCE_DIR}" + mkdir -p "${SEQUENCE_DIR}" + + # Delete any 0=length files + find "${DATE_DIR}" -name "*.${EXTENSION}" -size 0 -delete + + # capture the "ln" commands in case the user needs to debug + mkdir -p "${ALLSKY_TMP}" + TMP="${ALLSKY_TMP}/timelapseTMP.txt" + > "${TMP}" + ls -rt "${DATE_DIR}"/*.${EXTENSION} | gawk 'BEGIN{ a=1 } { printf "ln -s %s '$DIR'/sequence/%04d.'$EXTENSION'\n", $0, a; - printf "ln -s %s '$DIR'/sequence/%04d.'$EXTENSION'\n", $0, a >> "'$TMP'"; - # if (a % 100 == 0) printf "echo '$ME': %d links created so far\n", a; + printf "ln -s %s '$DIR'/sequence/%04d.'$EXTENSION'\n", $0, a >> "'${TMP}'"; a++; }' | bash # Make sure there's at least one link. - NUM_FILES=$(wc -l < ${TMP}) + NUM_FILES=$(wc -l < "${TMP}") if [ $NUM_FILES -eq 0 ]; then - echo -en "*** ${ME}: ${RED}ERROR: No links found!${NC}\n" - rmdir "${DIR}/sequence" + echo -en "${RED}*** ${ME}: ERROR: No images found!${NC}\n" + rmdir "${SEQUENCE_DIR}" exit 1 else - echo -e "$ME: Created $NUM_FILES links total\n" + echo "${ME}: Processing ${NUM_FILES} images..." fi else echo -en "${ME}: ${YELLOW}Not regenerating sequence because KEEP_SEQUENCE was given and $NSEQ links are present ${NC}\n" @@ -86,69 +89,43 @@ fi SCALE="" TIMELAPSEWIDTH=${TIMELAPSEWIDTH:-0} - +TIMELAPSEHEIGHT=${TIMELAPSEHEIGHT:-0} if [ "${TIMELAPSEWIDTH}" != 0 ]; then - SCALE="-filter:v scale=${TIMELAPSEWIDTH:0}:${TIMELAPSEHEIGHT:0}" - echo "$ME: Using video scale ${TIMELAPSEWIDTH} * ${TIMELAPSEHEIGHT}" + SCALE="-filter:v scale=${TIMELAPSEWIDTH}:${TIMELAPSEHEIGHT}" + echo "$ME: Using video scale ${TIMELAPSEWIDTH}x${TIMELAPSEHEIGHT}" fi # "-loglevel warning" gets rid of the dozens of lines of garbage output # but doesn't get rid of "deprecated pixel format" message when -pix_ftm is "yuv420p". -# set FFLOG=info in config.sh if you want to see what's going on for debugging +# set FFLOG=info in config.sh if you want to see what's going on for debugging. +OUTPUT_FILE="${DATE_DIR}/allsky-${DATE}.mp4" ffmpeg -y -f image2 \ -loglevel ${FFLOG:-warning} \ -r ${FPS:-25} \ - -i $DIR/sequence/%04d.$EXTENSION \ + -i ${SEQUENCE_DIR}/%04d.${EXTENSION} \ -vcodec ${VCODEC:-libx264} \ -b:v ${TIMELAPSE_BITRATE:-2000k} \ - -pix_fmt yuv420p \ + -pix_fmt ${PIX_FMT:-yuv420p} \ -movflags +faststart \ $SCALE \ - $DIR/allsky-$DAY.mp4 + ${TIMELAPSE_PARAMETERS} \ + ${OUTPUT_FILE} RET=$? if [ $RET -ne 0 ]; then echo -e "\n${RED}*** $ME: ERROR: ffmpeg failed with RET=$RET" - echo "Links in '$DIR/sequence' left for debugging." + echo "Links in '${SEQUENCE_DIR}' left for debugging." echo -e "Remove them when the problem is fixed.${NC}\n" exit 1 fi -if [ "$UPLOAD_VIDEO" = true ] ; then - if [[ "$PROTOCOL" == "S3" ]] ; then - $AWS_CLI_DIR/aws s3 cp $DIR/allsky-$DAY.mp4 s3://$S3_BUCKET$MP4DIR --acl $S3_ACL & - elif [[ $PROTOCOL == "local" ]] ; then - cp $DIR/allsky-$DAY.mp4 $MP4DIR & - else - # This sometimes fails with "mv: Access failed: 550 The process cannot access the file because it is being used by another process. (cp)". - # xxxx Could it be because the web server is trying to access the file at the same time? - # If so, should we wait a few seconds and try lftp again? - # This probably isn't an issue with .jpg files since they are much smaller and the window for - # simultaneous access is much smaller. - - # "put" to a temp name, then move the temp name to the final name. - # This is because slow uplinks can cause multiple lftp requests to be running at once, - # and only one lftp can upload the file at once, otherwise get this error: - # put: Access failed: 550 The process cannot access the file because it is being used by another process. (image.jpg) - # Slow uploads also cause a problem with web pages that try to read the file as it's being uploaded. - # "tl" = "time lapse" - use a unique temporary name - TEMP_NAME="tl-$RANDOM" - ( - FILE="allsky-$DAY.mp4" - FULL_FILE="/$DIR/$FILE" - lftp "$PROTOCOL://$USER:$PASSWORD@$HOST:$MP4DIR" -e "set net:max-retries 1; put "$FULL_FILE" -o $TEMP_NAME; rm -f "$FILE"; mv $TEMP_NAME "$FILE"; bye" - RET=$? - if [ $RET -ne 0 ]; then - echo "${RED}*** $ME: ERROR: lftp failed with RET=$RET on '$FULL_FILE'${NC}" - fi - ) & - fi -fi - if [ -z "$KEEP_SEQUENCE" ] ; then - echo -en "${ME}: ${GREEN}Deleting sequence${NC}\n" rm -rf $DIR/sequence else echo -en "${ME}: ${GREEN}Keeping sequence${NC}\n" fi echo -en "${ME}: ${GREEN}Timelapse was created${NC}\n" + +# timelapse is uploaded via endOfNight.sh, which called us. + +exit 0 From bb6ad28d85885d7ebf9c1486f0ddc9ae0c407dce Mon Sep 17 00:00:00 2001 From: EricClaeys <83164203+EricClaeys@users.noreply.github.com> Date: Wed, 29 Sep 2021 19:28:21 -0500 Subject: [PATCH 08/18] Centralize upload --- scripts/uploadForDay.sh | 59 ++++++----------------------------------- 1 file changed, 8 insertions(+), 51 deletions(-) diff --git a/scripts/uploadForDay.sh b/scripts/uploadForDay.sh index c6ffc07b2..ca5a9fefb 100755 --- a/scripts/uploadForDay.sh +++ b/scripts/uploadForDay.sh @@ -1,57 +1,14 @@ #!/bin/bash -source $ALLSKY_HOME/config.sh -source $ALLSKY_HOME/scripts/filename.sh -source $ALLSKY_HOME/scripts/ftp-settings.sh -cd $ALLSKY_HOME/scripts +# This script allows the user to manually upload the keogram, startrails, and timelapse files. +# It uses the "generateForDay.sh" script to do the work. -ME="$(basename "$BASH_ARGV0")" # Include script name in output so it's easier to find in the log file - -RED='\033[0;31m' -GREEN='\033[0;32m' -NC='\033[0m' # No Color - -if [ $# -lt 1 ] - then - echo -en "${ME}: ${RED}You need to pass a day argument\n" - echo -en " ex: $ME 20180119${NC}\n" - exit 3 +# Allow this script to be executed manually, which requires ALLSKY_HOME to be set. +if [ -z "${ALLSKY_HOME}" ] ; then + export ALLSKY_HOME="$(realpath $(dirname "${BASH_ARGV0}")/..)" fi -DIR="$ALLSKY_HOME/images/$1" - -# Upload keogram -echo -e "${ME}: Uploading Keogram\n" -KEOGRAM="$DIR/keogram/keogram-$1.$EXTENSION" -if [[ $PROTOCOL == "S3" ]] ; then - $AWS_CLI_DIR/aws s3 cp "$KEOGRAM" "s3://$S3_BUCKET$KEOGRAM_DIR" --acl $S3_ACL & -elif [[ $PROTOCOL == "local" ]] ; then - cp "$KEOGRAM" "$KEOGRAM_DIR" & -else - lftp "$PROTOCOL://$USER:$PASSWORD@$HOST:$KEOGRAM_DIR" -e "set net:max-retries 1; put "$KEOGRAM"; bye" & -fi -echo -e "\n" +source "${ALLSKY_HOME}/variables.sh" -# Upload Startrails -echo -e "${ME}: Uploading Startrails\n" -STARTRAILS="$DIR/startrails/startrails-$1.$EXTENSION" -if [[ $PROTOCOL == "S3" ]] ; then - $AWS_CLI_DIR/aws s3 cp "$STARTRAILS" "s3://$S3_BUCKET$STARTRAILS_DIR" --acl $S3_ACL & -elif [[ $PROTOCOL == "local" ]] ; then - cp "$STARTRAILS" "$STARTRAILS_DIR" & -else - lftp "$PROTOCOL://$USER:$PASSWORD@$HOST:$STARTRAILS_DIR" -e "set net:max-retries 1; put "$STARTRAILS"; bye" & -fi -echo -e "\n" - -# Upload timelapse -echo -e "${ME}: Uploading Timelapse\n" -TIMELAPSE="$DIR/allsky-$1.mp4" -if [[ "$PROTOCOL" == "S3" ]] ; then - $AWS_CLI_DIR/aws s3 cp "$TIMELAPSE" "s3://$S3_BUCKET$MP4DIR" --acl $S3_ACL & -elif [[ $PROTOCOL == "local" ]] ; then - cp "$TIMELAPSE" "$MP4DIR" & -else - lftp "$PROTOCOL://$USER:$PASSWORD@$HOST:$MP4DIR" -e "set net:max-retries 1; put "$TIMELAPSE"; bye" & -fi -echo -e "\n" +# "--upload" tells the script to do an upload rather than create. +"${ALLSKY_SCRIPTS}/generateForDay.sh" --upload "$@" From 192b1a5b77c6ef18862026259807a467f2cf69bc Mon Sep 17 00:00:00 2001 From: EricClaeys <83164203+EricClaeys@users.noreply.github.com> Date: Wed, 29 Sep 2021 19:52:33 -0500 Subject: [PATCH 09/18] Centralize upload --- scripts/generateForDay.sh | 187 ++++++++++++++++++++++++++++++++------ 1 file changed, 157 insertions(+), 30 deletions(-) diff --git a/scripts/generateForDay.sh b/scripts/generateForDay.sh index 6e4653375..c23c0f0a0 100755 --- a/scripts/generateForDay.sh +++ b/scripts/generateForDay.sh @@ -1,41 +1,168 @@ #!/bin/bash -# This script allows users to manually generate keograms,startrails, and timelapses, -# outside of the ones generated automatically. -source $ALLSKY_HOME/config.sh -source $ALLSKY_HOME/scripts/filename.sh +# This script allows users to manually generate or upload keograms,startrails, and timelapses. -cd $ALLSKY_HOME/scripts +ME="$(basename "${BASH_ARGV0}")" -ME="$(basename "$BASH_ARGV0")" # Include script name in output so it's easier to find in the log file +# Allow this script to be executed manually, which requires several variables to be set. +if [ -z "${ALLSKY_HOME}" ] ; then + export ALLSKY_HOME=$(realpath $(dirname "${BASH_ARGV0}")/..) +fi + +# If the first argument is "--upload" then we upload files, otherwise we create them. +if [ "$1" = "--upload" ]; then + shift + TYPE="UPLOAD" + MSG1="upload" + MSG2="uploaded" +else + TYPE="GENERATE" + MSG1="create" + MSG2="created" +fi + +source "${ALLSKY_HOME}/variables.sh" +source "${ALLSKY_CONFIG}/config.sh" +source "${ALLSKY_SCRIPTS}/filename.sh" +[ "${TYPE}" = "UPLOAD" ] && source "${ALLSKY_SCRIPTS}/ftp-settings.sh" -RED='\033[0;31m' -GREEN='\033[0;32m' -NC='\033[0m' # No Color -if [ $# -lt 1 ] - then - echo -en "${ME}: ${RED}You need to pass a day argument\n" - echo -en " ex: ${ME} 20180119${NC}\n" - exit 3 +if [ $# -eq 0 -o "${1}" = "-h" -o "${1}" = "--help" ]; then + echo -en "${RED}" + echo -e "Usage: ${ME} [-k] [-s] [-t] DATE" + echo -e " where:" + echo -e " 'DATE' is the day in '${ALLSKY_IMAGES}' to process" + echo -e " 'k' is to ${MSG1} a keogram" + echo -e " 's' is to ${MSG1} a startrail" + echo -e " 't' is to ${MSG1} a timelapse" + echo -e " If you don't specify k, s, or t, all three will be ${MSG2}." + echo -e "${NC}" + exit 0 fi -DATE=$1 -DIR="$ALLSKY_HOME/images/$DATE" +if [ $# -gt 1 ] ; then + DO_K="false" + DO_S="false" + DO_T="false" + while [ $# -gt 1 ] + do + if [ "${1}" = "-k" ] ; then + DO_K="true" + elif [ "${1}" = "-s" ] ; then + DO_S="true" + elif [ "${1}" = "-t" ] ; then + DO_T="true" + else + echo "Unknown image type: '${1}'; ignoring." + fi + shift + done +else + DO_K="true" + DO_S="true" + DO_T="true" +fi + +DATE="${1}" +DATE_DIR="${ALLSKY_IMAGES}/${DATE}" +if [ ! -d "${DATE_DIR}" ] ; then + echo -e "${ME}: ${RED}ERROR: '${DATE_DIR}' not found!${NC}" + exit 2 +fi -# Generate timelapse from collected images -echo -e "${ME}: Generating Keogram\n" -mkdir -p ${DIR}/keogram/ -../keogram ${DIR}/ $EXTENSION ${DIR}/keogram/keogram-$DATE.jpg -echo -e "\n" +if [ "${DO_K}" = "true" ] ; then + KEOGRAM_FILE="keogram-${DATE}.${EXTENSION}" + UPLOAD_FILE="${DATE_DIR}/keogram/${KEOGRAM_FILE}" + if [ "${TYPE}" = "GENERATE" ]; then + # Don't include ${ME} since this script is always executed manually + echo -e "===== Generating Keogram" + mkdir -p "${DATE_DIR}/keogram" -# Generate startrails from collected images. Treshold set to 0.1 by default in config.sh to avoid stacking over-exposed images -echo -e "${ME}: Generating Startrails\n" -mkdir -p ${DIR}/startrails -../startrails ${DIR}/ $EXTENSION $BRIGHTNESS_THRESHOLD ${DIR}/startrails/startrails-$DATE.jpg -echo -e "\n" + # The keogram command outputs one line for each of the many hundreds of files, + # and this adds needless clutter to the output, so send output to a tmp file so we + # can output the number of images. + TMP="${ALLSKY_TMP}/keogramTMP.txt" + "${ALLSKY_HOME}/keogram" -d "${DATE_DIR}" -e ${EXTENSION} -o "${UPLOAD_FILE}" ${KEOGRAM_PARAMETERS} > "${TMP}" + [ $? -eq 0 ] && echo -e "Completed" + else + if [ -s "${UPLOAD_FILE}" ]; then + # If the user specified a different name for the destination file, use it. + if [ "${KEOGRAM_DESTINATION_NAME}" != "" ]; then + KEOGRAM_FILE="${KEOGRAM_DESTINATION_NAME}" + fi + echo "Uploading ${KEOGRAM_FILE}" + # KG == KeoGram. "--silent" is for silent mode + "${ALLSKY_SCRIPTS}/upload.sh" --silent "${UPLOAD_FILE}" "${KEOGRAM_DIR}" "${KEOGRAM_FILE}" "KG" + [ $? -eq 0 ] && echo "${KEOGRAM_FILE} uploaded" + else + echo -en "${YELLOW}" + echo -n "ERROR: Keogram file '${UPLOAD_FILE}' not found; skipping" + echo -e "${NC}" + fi + fi + echo -e "\n" +fi + +if [ "${DO_S}" = "true" ] ; then + STARTRAILS_FILE="startrails-${DATE}.${EXTENSION}" + UPLOAD_FILE="${DATE_DIR}/startrails/${STARTRAILS_FILE}" + if [ "${TYPE}" = "GENERATE" ]; then + echo -e "===== Generating Startrails, threshold=${BRIGHTNESS_THRESHOLD}" + mkdir -p "${DATE_DIR}/startrails" + + # The staretrails command outputs one line for each of the many hundreds of files, + # and this adds needless clutter to the output, so send output to a tmp file so we + # can output the number of images. + TMP="${ALLSKY_TMP}/startrailsTMP.txt" + "${ALLSKY_HOME}/startrails" -d "${DATE_DIR}/" -e ${EXTENSION} -b "${BRIGHTNESS_THRESHOLD}" -o "${UPLOAD_FILE}" > "${TMP}" + [ $? -eq 0 ] && echo -e "Completed" + else + if [ -s "${UPLOAD_FILE}" ]; then + if [ "${STARTRAILS_DESTINATION_NAME}" != "" ]; then + STARTRAILS_FILE="${STARTRAILS_DESTINATION_NAME}" + fi + echo "Uploading ${STARTRAILS_FILE}" + # ST = Star Trails + "${ALLSKY_SCRIPTS}/upload.sh" --silent "${UPLOAD_FILE}" "${STARTRAILS_DIR}" "${STARTRAILS_FILE}" "ST" + [ $? -eq 0 ] && echo "${STARTRAILS_FILE} uploaded" + else + echo -en "${YELLOW}" + echo -n "WARNING: Startrails file '${UPLOAD_FILE}' not found; skipping" + echo -e "${NC}" + fi + fi + echo -e "\n" +fi + +if [ "${DO_T}" = "true" ] ; then + VIDEOS_FILE="allsky-${DATE}.mp4" + UPLOAD_FILE="${DATE_DIR}/${VIDEOS_FILE}" + if [ "${TYPE}" = "GENERATE" ]; then + echo -e "===== Generating Timelapse" + "${ALLSKY_SCRIPTS}/timelapse.sh" ${DATE} # it creates the necessary directory + [ $? -eq 0 ] && echo -e "Completed" + else + if [ -s "${UPLOAD_FILE}" ]; then + if [ "${VIDEOS_DESTINATION_NAME}" != "" ]; then + VIDEOS_FILE="${VIDEOS_DESTINATION_NAME}" + fi + echo "Uploading ${VIDEOS_FILE}" + # TL = Time Lapse + "${ALLSKY_SCRIPTS}/upload.sh" --silent "${UPLOAD_FILE}" "${VIDEOS_DIR}" "${VIDEOS_FILE}" "TL" + [ $? -eq 0 ] && echo "${VIDEOS_FILE} uploaded" + else + echo -en "${YELLOW}" + echo -n "ERROR: Timelapse file '${UPLOAD_FILE}' not found; skipping" + echo -e "${NC}" + fi + fi + echo -e "\n" +fi + +if [ "${TYPE}" = "GENERATE" ]; then + echo -e "\n================" + echo "If you want to upload the file(s) you just created, execute 'uploadForDay.sh ${DATE}" + echo "================" +fi -# Generate timelapse from collected images -echo -e "${ME}: Generating Timelapse\n" -./timelapse.sh $DATE -echo -e "\n" +exit 0 From 4e6ab34f0de2b791faf24c8b25541afdd8648deb Mon Sep 17 00:00:00 2001 From: EricClaeys <83164203+EricClaeys@users.noreply.github.com> Date: Wed, 29 Sep 2021 19:55:26 -0500 Subject: [PATCH 10/18] Centralize upload --- variables.sh | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 variables.sh diff --git a/variables.sh b/variables.sh new file mode 100644 index 000000000..938abcc0f --- /dev/null +++ b/variables.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +# This file is source'd into other files to set some variables used by scripts. +# This allows us to easily add and change directory names. +# It should only be called after $ALLSKY_HOME is set. + +if [ "${ALLSKY_VARIABLE_SET}" = "" ]; then + set -a # automatically export all variables + + ALLSKY_VARIABLE_SET="true" # so we only do the following once + + ME="$(basename "${BASH_ARGV0}")" + + # Set colors used by many scripts in output. + # If we're not on a tty output is likely being written to a file, so don't use colors. + if tty --silent ; then + RED="\033[0;31m" + GREEN="\033[0;32m" + YELLOW="\033[0;33m" + NC="\033[0m" # No Color + else + RED="" + GREEN="" + YELLOW="" + NC="" + fi + + if [ "${ALLSKY_HOME}" = "" ] ; then # This must come after setting colors above + echo -en "${RED}" + echo -n "${ME}: ERROR: ALLSKY_HOME not set! Exiting..." + echo -e "${NC}" + exit 1 + fi + + # Allow variables to be overridden for testing or to use different locations. + + # For temporary files or files that can be deleted at reboot. + ALLSKY_TMP="${ALLSKY_TMP:-${ALLSKY_HOME}/tmp}" + + # Central location for all AllSky configuration files. + # xxxxxx NEW NAME: ALLSKY_CONFIG${ALLSKY_CONFIG:-=${ALLSKY_HOME}/configuration} + ALLSKY_CONFIG="${ALLSKY_HOME}" # xxx old location + + # Holds all the scripts. + ALLSKY_SCRIPTS="${ALLSKY_SCRIPTS:-${ALLSKY_HOME}/scripts}" + + # Holds all the images on a per-day basis. + ALLSKY_IMAGES="${ALLSKY_IMAGES:-${ALLSKY_HOME}/images}" + + # Holds all the notification images. + ALLSKY_NOTIFICATION_IMAGES="${ALLSKY_NOTIFICATION_IMAGES:-${ALLSKY_HOME}/notification_images}" + + # Holds all the dark frames. + ALLSKY_DARKS="${ALLSKY_DARKS:-${ALLSKY_HOME}/darks}" +fi From e43c19d0bc8230449ccab17f8be90ec08003743c Mon Sep 17 00:00:00 2001 From: EricClaeys <83164203+EricClaeys@users.noreply.github.com> Date: Wed, 29 Sep 2021 20:03:41 -0500 Subject: [PATCH 11/18] Fixed IMAGES_DIR in copy_notification_image.sh --- scripts/copy_notification_image.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/copy_notification_image.sh b/scripts/copy_notification_image.sh index 01bd8dda7..9100338f5 100755 --- a/scripts/copy_notification_image.sh +++ b/scripts/copy_notification_image.sh @@ -41,8 +41,7 @@ fi # If at nighttime, save them in (possibly) yesterday's directory. # If during day, save in today's directory. if [ "${CAPTURE_24HR}" = "true" ] ; then - IMAGES_DIR="${ALLSKY_IMAGES}/$(date -d '12 hours ago' +'%Y%m%d')" - [ ! -d "${IMAGES_DIR}" ] && IMAGES_DIR="${ALLSKY_IMAGES}/$(date +'%Y%m%d')" + IMAGES_DIR="${ALLSKY_IMAGES}/$(date +'%Y%m%d')" THUMB="${IMAGES_DIR}/thumbnails/${FILENAME}-$(date +'%Y%m%d%H%M%S').${EXTENSION}" convert "${IMAGE_TO_USE}" -resize "${THUMBNAIL_SIZE_X}x${THUMBNAIL_SIZE_Y}" "${THUMB}" From 412fd78aae81e681e1b1ff9a00c69eadc5bf9cca Mon Sep 17 00:00:00 2001 From: EricClaeys <83164203+EricClaeys@users.noreply.github.com> Date: Wed, 29 Sep 2021 20:10:18 -0500 Subject: [PATCH 12/18] change spaces to tabs, endOfNight.sh --- scripts/endOfNight.sh | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/scripts/endOfNight.sh b/scripts/endOfNight.sh index 58ca7dca3..7128a1a67 100755 --- a/scripts/endOfNight.sh +++ b/scripts/endOfNight.sh @@ -31,8 +31,8 @@ fi # Post end of night data. This includes next twilight time if [[ ${POST_END_OF_NIGHT_DATA} == "true" ]]; then - echo -e "${ME}: Posting next twilight time to let server know when to resume liveview\n" - "${ALLSKY_SCRIPTS}/postData.sh" + echo -e "${ME}: Posting next twilight time to let server know when to resume liveview\n" + "${ALLSKY_SCRIPTS}/postData.sh" echo -e "\n" fi @@ -46,13 +46,12 @@ if [[ "${REMOVE_BAD_IMAGES}" == "true" ]]; then fi # Generate keogram from collected images -if [[ ${KEOGRAM} == "true" ]]; then - echo -e "${ME}: ===== Generating Keogram" - mkdir -p "${DATE_DIR}/keogram/" + echo -e "${ME}: ===== Generating Keogram" + mkdir -p "${DATE_DIR}/keogram/" KEOGRAM_FILE="keogram-${DATE}.${EXTENSION}" UPLOAD_FILE="${DATE_DIR}/keogram/${KEOGRAM_FILE}" - "${ALLSKY_HOME}/keogram" -d "${DATE_DIR}/" -e ${EXTENSION} -o "${UPLOAD_FILE}" ${KEOGRAM_PARAMETERS} + "${ALLSKY_HOME}/keogram" -d "${DATE_DIR}/" -e ${EXTENSION} -o "${UPLOAD_FILE}" ${KEOGRAM_PARAMETERS} RETCODE=$? if [[ ${UPLOAD_KEOGRAM} == "true" && ${RETCODE} = 0 ]] ; then # If the user specified a different name for the destination file, use it. @@ -67,21 +66,20 @@ if [[ ${KEOGRAM} == "true" ]]; then echo "${ME}: Copying ${UPLOAD_FILE} to ${WEB_KEOGRAM_DIR}" cp ${UPLOAD_FILE} "${WEB_KEOGRAM_DIR}" fi - fi + fi echo fi # Generate startrails from collected images. # Threshold set to 0.1 by default in config.sh to avoid stacking over-exposed images. if [[ ${STARTRAILS} == "true" ]]; then - echo -e "${ME}: ===== Generating Startrails" - mkdir -p ${DATE_DIR}/startrails/ + echo -e "${ME}: ===== Generating Startrails" + mkdir -p ${DATE_DIR}/startrails/ STARTRAILS_FILE="startrails-${DATE}.${EXTENSION}" UPLOAD_FILE="${DATE_DIR}/startrails/${STARTRAILS_FILE}" - - "${ALLSKY_HOME}/startrails" "${DATE_DIR}/" ${EXTENSION} ${BRIGHTNESS_THRESHOLD} "${UPLOAD_FILE}" + "${ALLSKY_HOME}/startrails" "${DATE_DIR}/" ${EXTENSION} ${BRIGHTNESS_THRESHOLD} "${UPLOAD_FILE}" RETCODE=$? - if [[ ${UPLOAD_STARTRAILS} == "true" && ${RETCODE} == 0 ]] ; then + if [[ ${UPLOAD_STARTRAILS} == "true" && ${RETCODE} == 0 ]] ; then # If the user specified a different name for the destination file, use it. if [ "${STARTRAILS_DESTINATION_NAME}" != "" ]; then STARTRAILS_FILE="${STARTRAILS_DESTINATION_NAME}" @@ -94,7 +92,7 @@ if [[ ${STARTRAILS} == "true" ]]; then echo "${ME}: Copying ${UPLOAD_FILE} to ${WEB_STARTRAILS_DIR}" cp "${UPLOAD_FILE}" "${WEB_STARTRAILS_DIR}" fi - fi + fi echo fi @@ -105,7 +103,7 @@ if [[ ${TIMELAPSE} == "true" ]]; then echo -e "${ME}: ===== Generating Timelapse" "${ALLSKY_SCRIPTS}/timelapse.sh" "${DATE}" RETCODE=$? - if [[ ${UPLOAD_VIDEO} == "true" && ${RETCODE} == 0 ]] ; then + if [[ ${UPLOAD_VIDEO} == "true" && ${RETCODE} == 0 ]] ; then VIDEOS_FILE="allsky-${DATE}.mp4" UPLOAD_FILE="${DATE_DIR}/${VIDEOS_FILE}" # If the user specified a different name for the destination file, use it. From c041e0107809bb67ed8fcb5fdcd9f4225474e56c Mon Sep 17 00:00:00 2001 From: EricClaeys <83164203+EricClaeys@users.noreply.github.com> Date: Wed, 29 Sep 2021 20:18:53 -0500 Subject: [PATCH 13/18] convert spaces to tabs, timelapse.sh --- scripts/timelapse.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/timelapse.sh b/scripts/timelapse.sh index 71f6ce48f..646b0a0f7 100755 --- a/scripts/timelapse.sh +++ b/scripts/timelapse.sh @@ -15,8 +15,8 @@ ME="$(basename "${BASH_ARGV0}")" cd $ALLSKY_HOME if [ $# -lt 1 -o $# -gt 2 -o "${1}" = "-h" -o "${1}" = "--help" ] ; then - TODAY=$(date +%Y%m%d) - echo -en "${RED}" + TODAY=$(date +%Y%m%d) + echo -en "${RED}" echo -n "Usage: ${ME} [--help] DATE [directory]" echo -e "${NC}" echo " example: ${ME} ${TODAY}" @@ -91,8 +91,8 @@ SCALE="" TIMELAPSEWIDTH=${TIMELAPSEWIDTH:-0} TIMELAPSEHEIGHT=${TIMELAPSEHEIGHT:-0} if [ "${TIMELAPSEWIDTH}" != 0 ]; then - SCALE="-filter:v scale=${TIMELAPSEWIDTH}:${TIMELAPSEHEIGHT}" - echo "$ME: Using video scale ${TIMELAPSEWIDTH}x${TIMELAPSEHEIGHT}" + SCALE="-filter:v scale=${TIMELAPSEWIDTH}:${TIMELAPSEHEIGHT}" + echo "$ME: Using video scale ${TIMELAPSEWIDTH}x${TIMELAPSEHEIGHT}" fi # "-loglevel warning" gets rid of the dozens of lines of garbage output From cbbd057bace0eb792054abc403ab4286bcf08299 Mon Sep 17 00:00:00 2001 From: EricClaeys <83164203+EricClaeys@users.noreply.github.com> Date: Thu, 30 Sep 2021 21:14:46 -0500 Subject: [PATCH 14/18] postData.sh: set correct timezone --- scripts/postData.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/postData.sh b/scripts/postData.sh index 6c6365028..d55af756f 100755 --- a/scripts/postData.sh +++ b/scripts/postData.sh @@ -10,7 +10,7 @@ ME="$(basename "${BASH_ARGV0}")" latitude=$(jq -r '.latitude' "${CAMERA_SETTINGS}") longitude=$(jq -r '.longitude' "${CAMERA_SETTINGS}") -timezone=-0700 +timezone=$(date "+%z") streamDaytime=false if [[ ${DAYTIME} == "true" || ${DAYTIME} == "1" ]] ; then From 46a5f858b33351a298cbef535564cd6499549af3 Mon Sep 17 00:00:00 2001 From: EricClaeys <83164203+EricClaeys@users.noreply.github.com> Date: Thu, 30 Sep 2021 21:22:55 -0500 Subject: [PATCH 15/18] generateForDay: made requested changes --- scripts/generateForDay.sh | 44 ++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/scripts/generateForDay.sh b/scripts/generateForDay.sh index c23c0f0a0..b7399d284 100755 --- a/scripts/generateForDay.sh +++ b/scripts/generateForDay.sh @@ -28,7 +28,7 @@ source "${ALLSKY_SCRIPTS}/filename.sh" if [ $# -eq 0 -o "${1}" = "-h" -o "${1}" = "--help" ]; then - echo -en "${RED}" + [ $# -eq 0 ] && echo -en "${RED}" echo -e "Usage: ${ME} [-k] [-s] [-t] DATE" echo -e " where:" echo -e " 'DATE' is the day in '${ALLSKY_IMAGES}' to process" @@ -36,31 +36,31 @@ if [ $# -eq 0 -o "${1}" = "-h" -o "${1}" = "--help" ]; then echo -e " 's' is to ${MSG1} a startrail" echo -e " 't' is to ${MSG1} a timelapse" echo -e " If you don't specify k, s, or t, all three will be ${MSG2}." - echo -e "${NC}" + [ $# -eq 0 ] && echo -e "${NC}" exit 0 fi if [ $# -gt 1 ] ; then - DO_K="false" - DO_S="false" - DO_T="false" + DO_KEOGRAM="false" + DO_STARTRAILS="false" + DO_TIMELAPSE="false" while [ $# -gt 1 ] do if [ "${1}" = "-k" ] ; then - DO_K="true" + DO_KEOGRAM="true" elif [ "${1}" = "-s" ] ; then - DO_S="true" + DO_STARTRAILS="true" elif [ "${1}" = "-t" ] ; then - DO_T="true" + DO_TIMELAPSE="true" else echo "Unknown image type: '${1}'; ignoring." fi shift done else - DO_K="true" - DO_S="true" - DO_T="true" + DO_KEOGRAM="true" + DO_STARTRAILS="true" + DO_TIMELAPSE="true" fi DATE="${1}" @@ -70,7 +70,7 @@ if [ ! -d "${DATE_DIR}" ] ; then exit 2 fi -if [ "${DO_K}" = "true" ] ; then +if [ "${DO_KEOGRAM}" = "true" ] ; then KEOGRAM_FILE="keogram-${DATE}.${EXTENSION}" UPLOAD_FILE="${DATE_DIR}/keogram/${KEOGRAM_FILE}" if [ "${TYPE}" = "GENERATE" ]; then @@ -78,11 +78,7 @@ if [ "${DO_K}" = "true" ] ; then echo -e "===== Generating Keogram" mkdir -p "${DATE_DIR}/keogram" - # The keogram command outputs one line for each of the many hundreds of files, - # and this adds needless clutter to the output, so send output to a tmp file so we - # can output the number of images. - TMP="${ALLSKY_TMP}/keogramTMP.txt" - "${ALLSKY_HOME}/keogram" -d "${DATE_DIR}" -e ${EXTENSION} -o "${UPLOAD_FILE}" ${KEOGRAM_PARAMETERS} > "${TMP}" + "${ALLSKY_HOME}/keogram" -d "${DATE_DIR}" -e ${EXTENSION} -o "${UPLOAD_FILE}" ${KEOGRAM_PARAMETERS} [ $? -eq 0 ] && echo -e "Completed" else if [ -s "${UPLOAD_FILE}" ]; then @@ -96,25 +92,21 @@ if [ "${DO_K}" = "true" ] ; then [ $? -eq 0 ] && echo "${KEOGRAM_FILE} uploaded" else echo -en "${YELLOW}" - echo -n "ERROR: Keogram file '${UPLOAD_FILE}' not found; skipping" + echo -n "WARNING: Keogram file '${UPLOAD_FILE}' not found; skipping" echo -e "${NC}" fi fi echo -e "\n" fi -if [ "${DO_S}" = "true" ] ; then +if [ "${DO_STARTRAILS}" = "true" ] ; then STARTRAILS_FILE="startrails-${DATE}.${EXTENSION}" UPLOAD_FILE="${DATE_DIR}/startrails/${STARTRAILS_FILE}" if [ "${TYPE}" = "GENERATE" ]; then echo -e "===== Generating Startrails, threshold=${BRIGHTNESS_THRESHOLD}" mkdir -p "${DATE_DIR}/startrails" - # The staretrails command outputs one line for each of the many hundreds of files, - # and this adds needless clutter to the output, so send output to a tmp file so we - # can output the number of images. - TMP="${ALLSKY_TMP}/startrailsTMP.txt" - "${ALLSKY_HOME}/startrails" -d "${DATE_DIR}/" -e ${EXTENSION} -b "${BRIGHTNESS_THRESHOLD}" -o "${UPLOAD_FILE}" > "${TMP}" + "${ALLSKY_HOME}/startrails" -d "${DATE_DIR}/" -e ${EXTENSION} -b "${BRIGHTNESS_THRESHOLD}" -o "${UPLOAD_FILE}" [ $? -eq 0 ] && echo -e "Completed" else if [ -s "${UPLOAD_FILE}" ]; then @@ -134,7 +126,7 @@ if [ "${DO_S}" = "true" ] ; then echo -e "\n" fi -if [ "${DO_T}" = "true" ] ; then +if [ "${DO_TIMELAPSE}" = "true" ] ; then VIDEOS_FILE="allsky-${DATE}.mp4" UPLOAD_FILE="${DATE_DIR}/${VIDEOS_FILE}" if [ "${TYPE}" = "GENERATE" ]; then @@ -152,7 +144,7 @@ if [ "${DO_T}" = "true" ] ; then [ $? -eq 0 ] && echo "${VIDEOS_FILE} uploaded" else echo -en "${YELLOW}" - echo -n "ERROR: Timelapse file '${UPLOAD_FILE}' not found; skipping" + echo -n "WARNING: Timelapse file '${UPLOAD_FILE}' not found; skipping" echo -e "${NC}" fi fi From 74d2cfeddc2d665b0f15e62c8a704f9ccd4a6db5 Mon Sep 17 00:00:00 2001 From: EricClaeys <83164203+EricClaeys@users.noreply.github.com> Date: Thu, 30 Sep 2021 21:29:37 -0500 Subject: [PATCH 16/18] saveImageDay: made requested updates --- scripts/saveImageDay.sh | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/scripts/saveImageDay.sh b/scripts/saveImageDay.sh index e90f49ae3..e21231db0 100755 --- a/scripts/saveImageDay.sh +++ b/scripts/saveImageDay.sh @@ -15,8 +15,7 @@ IMAGE_TO_USE="$FULL_FILENAME" # Quick check to make sure the image isn't corrupted. identify "$IMAGE_TO_USE" >/dev/null 2>&1 -RET=$? -if [ $RET -ne 0 ] ; then +if [ $? -ne 0 ] ; then echo "${RED}*** $ME: ERROR: Image '${IMAGE_TO_USE} is corrupt; ignoring.${NC}" exit 3 fi @@ -24,9 +23,8 @@ fi # Resize the image if required if [[ $IMG_RESIZE == "true" ]]; then convert "$IMAGE_TO_USE" -resize "$IMG_WIDTH"x"$IMG_HEIGHT" "$IMAGE_TO_USE" - RET=$? - if [ $RET -ne 0 ] ; then - echo "${RED}*** $ME: ERROR: IMG_RESIZE failed with RET=$RET${NC}" + if [ $? -ne 0 ] ; then + echo "${RED}*** $ME: ERROR: IMG_RESIZE failed${NC}" exit 4 fi fi @@ -34,9 +32,8 @@ fi # Crop the image around the center if required if [[ $CROP_IMAGE == "true" ]]; then convert "$IMAGE_TO_USE" -gravity Center -crop "$CROP_WIDTH"x"$CROP_HEIGHT"+"$CROP_OFFSET_X"+"$CROP_OFFSET_Y" +repage "$IMAGE_TO_USE" - RET=$? - if [ $RET -ne 0 ] ; then - echo "${RED}*** $ME: ERROR: CROP_IMAGE failed with RET=$RET${NC}" + if [ $? -ne 0 ] ; then + echo "${RED}*** $ME: ERROR: CROP_IMAGE failed${NC}" exit 4 fi fi @@ -62,9 +59,8 @@ if [ "${CAPTURE_24HR}" = "true" -o "${DAYTIME_SAVE}" = "true" ] ; then # If we resized above, this will be a resize of a resize, # but for thumbnails it should be ok. convert "$IMAGE_TO_USE" -resize "${THUMBNAIL_SIZE_X}x${THUMBNAIL_SIZE_Y}" "$THUMBNAILS_DIR/$SAVED_FILE" - RET=$? - if [ $RET -ne 0 ] ; then - echo "*** $ME: ERROR: THUMBNAIL resize failed with RET=$RET; continuing." + if [ $? -ne 0 ] ; then + echo "*** $ME: ERROR: THUMBNAIL resize failed; continuing." fi fi @@ -73,12 +69,14 @@ if [ "$UPLOAD_IMG" = true ] ; then if [[ "$RESIZE_UPLOADS" == "true" ]]; then # Create a smaller version for upload convert "$IMAGE_TO_USE" -resize "$RESIZE_UPLOADS_SIZE" -gravity East -chop 2x0 "$IMAGE_TO_USE" - RET=$? - if [ $RET -ne 0 ] ; then - echo -e "${YELLOW}*** ${ME}: WARNING: RESIZE_UPLOADS failed with RET=${RET}; continuing with larger image.${NC}" + if [ $? -ne 0 ] ; then + echo -e "${YELLOW}*** ${ME}: WARNING: RESIZE_UPLOADS failed; continuing with larger image.${NC}" fi fi + # SI == Save Image "${ALLSKY_SCRIPTS}/upload.sh" "${IMAGE_TO_USE}" "${IMGDIR}" "${IMAGE_TO_USE}" "SI" + exit $? fi + exit 0 From 2b80cb655b6706a49927f7bcdb88d010f719ff13 Mon Sep 17 00:00:00 2001 From: EricClaeys <83164203+EricClaeys@users.noreply.github.com> Date: Thu, 30 Sep 2021 21:35:22 -0500 Subject: [PATCH 17/18] upload.sh: s/jgp/jpg/ --- scripts/upload.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/upload.sh b/scripts/upload.sh index 8a7109b99..d5d1b606b 100644 --- a/scripts/upload.sh +++ b/scripts/upload.sh @@ -34,7 +34,7 @@ if [ $# -lt 3 ] ; then echo " 'directory' is the directory ON THE SERVER the file should be uploaded to." echo " 'destination_file_name' is the name the file should be called ON THE SERVER." echo - echo -n "For example: ${ME} keogram-20210710.jgp /keograms keogram.jpg" + echo -n "For example: ${ME} keogram-20210710.jpg /keograms keogram.jpg" exit 1 fi FILE_TO_UPLOAD="${1}" From e5bb84699b7e34a242b9c98e662faa5e465edb6c Mon Sep 17 00:00:00 2001 From: EricClaeys <83164203+EricClaeys@users.noreply.github.com> Date: Thu, 30 Sep 2021 21:38:56 -0500 Subject: [PATCH 18/18] generateForDay.sh Fixes #518