#!/usr/bin/env bash
#
# Download every file listed in download.txt (Google Drive links)
# into ./pdfs/, preserving the "Book Name" filenames.
#
# Usage:
# ./download_all.sh [download.txt] [dest_dir]
# ./download_all.sh --force # re-download even if the file exists
#
set -euo pipefail
SRC_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LIST="$SRC_DIR/download.txt"
DEST="$SRC_DIR/pdfs"
FORCE=0
for arg in "$@"; do
case "$arg" in
--force) FORCE=1 ;;
*) if [[ -f "$arg" ]]; then LIST="$arg"; else DEST="$arg"; fi ;;
esac
done
mkdir -p "$DEST"
command -v curl >/dev/null 2>&1 || { echo "ERROR: curl is required." >&2; exit 1; }
# Download one Google Drive file by its file ID.
dl_drive_file() {
local id="$1" out="$2"
local cookies tmp
cookies="$(mktemp)"
tmp="${out}.part"
rm -f "$tmp"
if command -v gdown >/dev/null 2>&1; then
gdown --id "$id" -O "$tmp"
else
# First attempt (works directly for small files).
curl -sSL -c "$cookies" "https://drive.google.com/uc?export=download&id=${id}" -o "$tmp"
# Large files return a virus-scan interstitial HTML page instead of the
# file; re-request by submitting its download form (action on
# drive.usercontent.google.com with id/export/confirm/uuid fields).
if head -c 2048 "$tmp" 2>/dev/null | grep -qi 'html'; then
local action query
action="$(grep -o '<form[^>]*action="[^"]*"' "$tmp" | head -n1 | sed 's/.*action="//;s/"//')"
query="$(grep -o 'name="[a-zA-Z]*" value="[^"]*"' "$tmp" | sed 's/name="//;s/" value="/=/;s/"//' | paste -sd'&' -)"
if [[ -n "${action:-}" && -n "${query:-}" ]]; then
curl -sSL -b "$cookies" "${action}?${query}" -o "$tmp"
fi
fi
fi
rm -f "$cookies"
# Sanity check: refuse to silently keep an HTML error page as the "pdf".
mv -f "$tmp" "$out"
# Sanity check: refuse to silently keep an HTML error page as the "pdf".
if head -c 2048 "$out" 2>/dev/null | grep -qi '<html'; then
echo " WARNING: got an HTML page instead of the file (link may need access). Saved for inspection: $out" >&2
return 1
fi
}
declare -A SEEN=()
total="$(($(wc -l < "$LIST") - 1))"
i=0
while IFS=$'\t' read -r name link || [[ -n "${name:-}" ]]; do
i=$((i + 1))
[[ -z "${name:-}" || -z "${link:-}" ]] && continue
id="$(printf '%s' "$link" | sed -n 's#.*/file/d/\([^/?]*\).*#\1#p')"
if [[ -z "$id" ]]; then echo "[$i/$total] SKIP (no file id): $name" >&2; continue; fi
# De-duplicate display names: the list contains e.g. two different
# "Rgveda darshana vol 11.pdf" links -> second becomes "vol 11 (2).pdf".
target="$name"
count="${SEEN["$name"]:-0}"
SEEN["$name"]=$((count + 1))
if ((count > 0)); then
if [[ "$name" == *.* ]]; then
target="${name%.*} ($((count + 1))).${name##*.}"
else
target="$name ($((count + 1)))"
fi
fi
out="$DEST/$target"
if [[ -e "$out" && $FORCE -eq 0 ]]; then
echo "[$i/$total] SKIP (exists): $target"
continue
fi
echo "[$i/$total] Downloading: $target"
dl_drive_file "$id" "$out" || true
done < <(tail -n +2 "$LIST")
echo "Done. Files are in: $DEST"