Marty Oehme
3e00e84319
When adding new links to vidl, it will now put them in a queue (file) from which it then begins downloading links one after the other. Only one downloading instance of vidl will ever be running, but you can still add more links by invoking it again while it is. Added one new command line option `-c` to quickly empty the queue and start over. Fixes #8.
191 lines
4.5 KiB
Bash
Executable file
191 lines
4.5 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# download a file if it does not exist in the archive alread
|
|
# otherwise just re-link it from the archive
|
|
|
|
show_help() {
|
|
printf """
|
|
archive.sh: Hard linking your stuff.
|
|
vidl: Video downloader
|
|
|
|
Simple wrapper for youtube-dl (or yt-dlp or similar).
|
|
|
|
Usage: vidl [OPTION] <link>
|
|
|
|
Point it to a link you want downloaded.
|
|
|
|
Options:
|
|
|
|
-h Display this help.
|
|
|
|
-d Directory to check for existence of file and archive to if needed.
|
|
If this is passed will not download existing archived files again.
|
|
|
|
-f Directory to download to.
|
|
|
|
-c Clear existing download queue.
|
|
|
|
-t Point to youtube-dl command to use. Can be command or absolute link.
|
|
By default will use \`yt-dlp\` which is a more up to date fork of the
|
|
youtube-dl program.
|
|
"""
|
|
}
|
|
|
|
urls=("$@")
|
|
|
|
while getopts "t:f:d:hc" opt; do
|
|
case "$opt" in
|
|
# v) verbose=1
|
|
# ;;
|
|
f)
|
|
DL_FOLDER="$OPTARG"
|
|
;;
|
|
t)
|
|
YT_DL_CMD="$OPTARG"
|
|
;;
|
|
d)
|
|
ARCHIVE_FOLDER="$OPTARG"
|
|
;;
|
|
c)
|
|
ONLY_DO=clear
|
|
;;
|
|
h | \? | *)
|
|
show_help
|
|
exit 0
|
|
;;
|
|
esac
|
|
done
|
|
shift $((OPTIND - 1))
|
|
|
|
get_ytdl_fname() {
|
|
yt_dl_fname=$("$YT_DL_CMD" --get-filename -o "$YT_DL_TITLE" "$*")
|
|
if [ -z "$yt_dl_fname" ]; then
|
|
echo Could not get video filename, error with youtube-dl.
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
_call_archive() { # 1=new_file, 2=archive_location
|
|
command -v archive >/dev/null 2>&1 || {
|
|
echo "archive command not found."
|
|
exit 1
|
|
}
|
|
archive -d "$2" -a "$1"
|
|
}
|
|
|
|
vid_ext="\(mp4\|avi\|webm\|mkv\|mpe?g\|3gp\|m4a\)"
|
|
_findfile() { # 1=directory, 2=file
|
|
find "$1" -type f -name "$2.*" | sed -ne "/$2\.$vid_ext$/Ip"
|
|
}
|
|
|
|
_alreadyexists() { # 1=video_regex
|
|
if [ ! -d "$ARCHIVE_FOLDER" ]; then return 0; fi
|
|
local found
|
|
found=$(_findfile "$ARCHIVE_FOLDER" "$1")
|
|
if [ -n "$found" ]; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
_download_cmd() {
|
|
"$YT_DL_CMD" \
|
|
-o "$DL_FOLDER/$YT_DL_TITLE.%(ext)s" \
|
|
"${YT_DL_OPTS[@]}" \
|
|
"$*"
|
|
}
|
|
|
|
download() { # 1=url
|
|
# # download the video to download folder
|
|
if ! _alreadyexists "$yt_dl_fname"; then
|
|
_download_cmd "$*"
|
|
|
|
# yt-dl never knows the exact filename in advance
|
|
file=$(_findfile "$DL_FOLDER" "$yt_dl_fname")
|
|
if [ -z "$file" ]; then exit 1; fi
|
|
_call_archive "$file" "$ARCHIVE_FOLDER"
|
|
# only link old file if one exists
|
|
else
|
|
archive_file=$(_findfile "$ARCHIVE_FOLDER" "$yt_dl_fname")
|
|
echo "$archive_file" | while read -r file; do
|
|
echo "file $file exists, not downloading duplicate"
|
|
_call_archive "$file" "$DL_FOLDER"
|
|
done
|
|
fi
|
|
}
|
|
|
|
setup() {
|
|
DL_FOLDER="${DL_FOLDER:-${XDG_VIDEOS_DIR:-$HOME/videos}}/inbox"
|
|
ARCHIVE_FOLDER="${ARCHIVE_FOLDER:-${XDG_VIDEOS_DIR:-$HOME/videos}}/archive"
|
|
YT_DL_CMD="${YT_DL_CMD:-yt-dlp}"
|
|
yt_default_opts=(-f "best[height\<=1080]" --retries 15 --embed-subs --sub-lang "en,de,es,fr")
|
|
declare -a YT_DL_OPTS=${YT_DL_OPTS:-( "${yt_default_opts[@]}" )}
|
|
YT_DL_TITLE="${YT_DL_TITLE:-%(channel)s_%(title)s_%(id)s}" # this title needs to be without extension
|
|
|
|
queue_file="${XDG_CACHE_HOME:-$HOME/.cache}/vidl_queue"
|
|
if [ ! -f "$queue_file" ]; then
|
|
mkdir -p $(dirname "$queue_file")
|
|
touch "$queue_file"
|
|
fi
|
|
lock_dir="${XDG_CACHE_HOME:-$HOME/.cache}/vidl_lock"
|
|
}
|
|
|
|
is_in_queue() { # 1=url
|
|
[ -f "$queue_file" ] || return 1
|
|
grep -q "$1" "$queue_file"
|
|
}
|
|
|
|
add_to_queue() { # 1=url
|
|
if is_in_queue "$1"; then return; fi
|
|
echo "$1" >>"$queue_file"
|
|
echo "added $url to queue."
|
|
}
|
|
|
|
remove_from_queue() { # 1=url
|
|
sed -i.bak -e "\|$1|d" "$queue_file"
|
|
}
|
|
|
|
clear_queue() {
|
|
rm "$queue_file"
|
|
}
|
|
|
|
remove_lock() {
|
|
if ! rmdir $lock_dir; then
|
|
echo "Failed to remove lock '$lock_dir'. Please remove manually before next run."
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
is_only_instance() {
|
|
if mkdir $lock_dir 2>/dev/null; then
|
|
trap "remove_lock" EXIT
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
main() {
|
|
setup
|
|
if [ "$ONLY_DO" = "clear" ]; then
|
|
clear_queue
|
|
exit
|
|
fi
|
|
|
|
for url in $*; do
|
|
add_to_queue "$url"
|
|
done
|
|
if is_only_instance; then
|
|
echo "Download starting..."
|
|
while read -r line; do
|
|
get_ytdl_fname "$line"
|
|
download "$line"
|
|
remove_from_queue "$line"
|
|
done <"$queue_file"
|
|
else
|
|
echo "Download already running, only adding to queue."
|
|
fi
|
|
echo "Download done..."
|
|
}
|
|
|
|
main "${urls[@]}"
|