You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
168 lines
4.3 KiB
168 lines
4.3 KiB
#!/usr/bin/env bash
|
|
|
|
# Exit 1 if any command errors
|
|
set -e
|
|
|
|
# $1 here is the first argument to this script
|
|
BATCH_FILE="$1"
|
|
|
|
DOWNLOAD_DIR="/export/jellyfin"
|
|
YTDLP_LOG_FILE="/export/ytdlp.log"
|
|
|
|
# 'cat << 'EOF"' is used here to allow for newlines in the command
|
|
YTDLP_COMMAND=$(cat << EOF
|
|
/srv/.local/bin/yt-dlp
|
|
-P $DOWNLOAD_DIR
|
|
--sub-format srt
|
|
--write-subs
|
|
--write-thumbnail
|
|
EOF
|
|
)
|
|
|
|
printUsage() {
|
|
cat << EOF
|
|
Usage: $(basename "$0") <batch.txt>
|
|
EOF
|
|
}
|
|
|
|
# log() takes a log level and log line and uses the LOG_LEVEL env var to
|
|
# control how/when it is logged
|
|
# To enable debug logging set LOG_LEVEL=debug as an env var
|
|
log() {
|
|
# '$1' is the first argument passed to this function
|
|
passed_level="$1"
|
|
|
|
# '$2' is the first argument passed to this function
|
|
log_line="$2"
|
|
|
|
# This is passed from the env as 'LOG_LEVEL='
|
|
env_level="$LOG_LEVEL"
|
|
|
|
# Convert env_level to int
|
|
case $env_level in
|
|
"DEBUG")
|
|
min_level_int=0;;
|
|
"INFO")
|
|
min_level_int=1;;
|
|
"ERROR")
|
|
min_level_int=2;;
|
|
*)
|
|
min_level_int=1;;
|
|
esac
|
|
|
|
# Convert passed_level to int
|
|
case $passed_level in
|
|
"DEBUG")
|
|
log_level_int=0;;
|
|
"INFO")
|
|
log_level_int=1;;
|
|
"ERROR")
|
|
log_level_int=1;;
|
|
*)
|
|
log_level_int=99;;
|
|
esac
|
|
|
|
if [ $log_level_int -ge $min_level_int ]; then
|
|
echo "[$passed_level] $log_line"
|
|
fi
|
|
}
|
|
|
|
validate_args() {
|
|
# If no argument specified, exit 1
|
|
if [ -z "$BATCH_FILE" ]; then
|
|
printUsage
|
|
exit 1
|
|
fi
|
|
|
|
# Exit 1 if passed batch file is not a file (or doesn't exist)
|
|
if [ ! -f "$BATCH_FILE" ]; then
|
|
echo "Error: Batch file '$BATCH_FILE' not found"
|
|
printUsage
|
|
exit 1
|
|
fi
|
|
|
|
# Exit 0 if passed file contains no urls
|
|
if ! grep -q "^.*http.*" "$BATCH_FILE"; then
|
|
echo "File '$BATCH_FILE' contains no URLs"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! -O "$BATCH_FILE" ]]; then
|
|
echo "File '$BATCH_FILE' is not owned by user ID '${UID}'"
|
|
echo "Run 'chown ${UID} $BATCH_FILE' before mounting"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! -O "$DOWNLOAD_DIR" ]]; then
|
|
echo "Directory '$DOWNLOAD_DIR' is not owned by user ID '${UID}'"
|
|
echo "Run 'chown -R ${UID} $DOWNLOAD_DIR' before mounting"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
process_batchfile() {
|
|
# Using `read` parse each line of the file as a '$line' while setting IFS=''
|
|
# to prevent lines containing things such as `\n` from being parsed as a
|
|
# literal newline
|
|
while IFS='' read -r line; do
|
|
# Ignore any commented lines RegEx explanation: https://regexr.com/7hs52
|
|
regex_match_leading_comment='^\s*[#].*$'
|
|
if [[ "$line" =~ $regex_match_leading_comment ]]; then
|
|
# RegEx explanation: https://regexr.com/7i073
|
|
line_without_comment=$(echo "$line" | sed 's/^\s*[#]\s*\(.*\)$/\1/')
|
|
log "INFO" "Skipping: $line_without_comment"
|
|
continue
|
|
fi
|
|
|
|
log "INFO" "Downloading: $line"
|
|
|
|
# Temporarily allow commands to fail without exiting
|
|
set +e
|
|
|
|
# Run the command with $line as an argument
|
|
# Quotes are used here as a measure to protect against "\n" and the like
|
|
# '>' is used to overwrite the log file each call so only the last commands
|
|
# output is shown
|
|
$YTDLP_COMMAND "$line" > $YTDLP_LOG_FILE 2>&1
|
|
|
|
# Save the exit code of the last command
|
|
exit_code="$?"
|
|
|
|
# Re-enable exiting 1 on command failure
|
|
set -e
|
|
|
|
if [ "$exit_code" -ne "0" ]; then
|
|
log "ERROR" "Command failed: '$YTDLP_COMMAND'"
|
|
cat $YTDLP_LOG_FILE
|
|
continue
|
|
fi
|
|
|
|
log "INFO" "Finished downloading '$line'"
|
|
|
|
# By here we can assume the file was downloaded successfully, thus we can
|
|
# comment out the line in the file
|
|
log "DEBUG" "Commenting out '$line' in '$BATCH_FILE'"
|
|
|
|
# Prepend a '#" on the current line in the file
|
|
# '|' is used because URLs contain '/' which is the usual sed delimiter
|
|
# 'cp' to a buffer file is used because sed cannot modify the mounted
|
|
# file's inode when using Docker ('-c' is not available in Ubuntu's sed)
|
|
new_file="/export/$(basename "$BATCH_FILE").new"
|
|
cp "$BATCH_FILE" "$new_file"
|
|
sed -i "s|\($line\)|# \1|" "$new_file"
|
|
cp "$new_file" "$BATCH_FILE"
|
|
|
|
log "DEBUG" "Finished commenting '$line' from '$BATCH_FILE'"
|
|
done <<< "$(cat "$BATCH_FILE")"
|
|
}
|
|
|
|
main() {
|
|
validate_args
|
|
|
|
log "INFO" "Processing $BATCH_FILE"
|
|
process_batchfile
|
|
log "INFO" "Finished processing $BATCH_FILE"
|
|
}
|
|
|
|
# Run main()
|
|
main
|
|
|