Created
April 7, 2016 15:30
-
-
Save brbsix/546b732a9578343b114b425691c7906f to your computer and use it in GitHub Desktop.
wkhtmltopdf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# Create a pdf from HTML or URL | |
cleanup(){ | |
# check whether $TEMPDIR exists and is a subdir of /tmp | |
if [[ -d $TEMPDIR && $(dirname "$TEMPDIR") = /tmp ]]; then | |
rm -rf "$TEMPDIR" | |
fi | |
} | |
error(){ | |
echo "ERROR: $@" >&2 | |
} | |
getbinaries(){ | |
local binaries bpath bversion flag tpath tversion | |
readarray -t binaries < <(which -a wkhtmltopdf) | |
if (( OPTION_NEW == 1 )) || (( OPTION_OLD == 1 )); then | |
declare -Al binmap | |
for bpath in "${binaries[@]}"; do | |
bversion=$(getversion "$bpath") | |
binmap["$bversion"]=$bpath | |
done | |
(( OPTION_NEW == 1 )) && flag=r | |
tversion=$(printf '%s\n' "${!binmap[@]}" | sort -V${flag} | head -n1) | |
tpath=${binmap["$tversion"]} | |
binaries=("$tpath") | |
fi | |
printf '%s\n' "${binaries[@]}" | |
} | |
getistring(){ | |
# get major version number | |
local mversion=$(getversion "$1" | cut -d. -f2) | |
if (( mversion >= 12 )); then | |
echo '--load-error-handling ignore' | |
else | |
echo '--ignore-load-errors' | |
fi | |
} | |
getoutput(){ | |
local bn destination fn output_determined output_supplied url | |
destination=$DESTINATION | |
url=$1 | |
output_supplied=$2 | |
if [[ -n $output_supplied ]]; then | |
# check whether supplied output is a destination directory | |
if [[ -d $output_supplied ]]; then | |
destination=$output_supplied | |
# check whether supplied output is a complete path | |
elif [[ -d $(dirname "$output_supplied") && $(dirname "$output_supplied") != . ]]; then | |
output_determined=$output_supplied | |
# check whether supplied output is a filename | |
else | |
output_determined=$destination/$output_supplied | |
fi | |
fi | |
if [[ -z $output_determined ]]; then | |
bn=$(basename "$url") | |
if [[ $bn = "$url" ]]; then | |
fn=$RANDOM | |
else | |
fn=$(sed 's/^\(.*\)\..*$/\1/' <<<"$bn") | |
fi | |
output_determined=${destination}/${fn}.pdf | |
fi | |
echo "$output_determined" | |
} | |
getversion(){ | |
"$1" --version | awk '/wkhtmltopdf/ {print $2; exit}' | |
} | |
makepdf(){ | |
local binaries binary istring output tempfile url | |
url=$1 | |
# determine actual destination path | |
output=$(getoutput "$url" "$2") | |
# ensure destination path does not already exist | |
if [[ -e $output ]]; then | |
error "'$output' already exists" | |
return 1 | |
fi | |
# ensure temp dir is removed upon exit | |
trap cleanup EXIT | |
# create temp dir | |
TEMPDIR=$(mktemp --directory --tmpdir makepdf-XXXXXX) | |
# generate temp file path (do not actually create the file yet) | |
tempfile=$(mktemp --dry-run --tmpdir="$TEMPDIR" XXXXXX.pdf) | |
readarray -t binaries < <(getbinaries) | |
for binary in "${binaries[@]}"; do | |
if (( OPTION_IGNORE == 1 )); then | |
istring=$(getistring "$binary") | |
fi | |
# execute wkhtmltopdf with options | |
"$binary" $istring "$url" "$tempfile" | |
STATUS=$? | |
if [[ -f $tempfile ]]; then | |
(( OPTION_OPEN == 1 )) && ! opener "$tempfile" && break | |
mkdir -p "$(dirname "$output")" && mv "$tempfile" "$output" && realpath "$output" && break | |
else | |
error "$binary failed to process '$url'" | |
return 1 | |
fi | |
done | |
} | |
opener(){ | |
local reply | |
"$PDFTOOL" "$1" | |
read -n1 -p "Keep file? " reply | |
echo | |
[[ $reply = [Yy] ]] | |
} | |
usage(){ | |
cat <<-EOF | |
Usage: $PROGRAM [OPTION]... URL [OUTPUT] | |
Leverage wkhtmltopdf to create a PDF from URL or HTML. | |
-i, --ignore ignore load errors | |
--new use newest version of wkhtmltopdf | |
--old use oldest version of wkhtmltopdf | |
-o, --open open pdf with $(basename "$PDFTOOL") after creation | |
$program accepts the following wkhtmltopdf options: | |
-l --lowquality | |
-n --disable-javascript | |
default binary: ${DEFAULT:-UNAVAILABLE} | |
default destination: ${DESTINATION} | |
EOF | |
exit 0 | |
} | |
version(){ | |
cat <<-EOF | |
$PROGRAM $VERSION | |
Copyright (c) 2015 Six ([email protected]) | |
EOF | |
exit 0 | |
} | |
PROGRAM=${0##*/} | |
VERSION='0.0.3' | |
DEFAULT=$(which wkhtmltopdf) | |
DESTINATION=$HOME/Downloads/wkhtmltopdf | |
PDFTOOL='evince' | |
if (( $# == 1 )); then | |
if [[ $1 =~ ^(-h|--help|help)$ ]]; then | |
usage | |
elif [[ $1 =~ ^(-v|--version|version)$ ]]; then | |
version | |
fi | |
fi | |
shopts='i,l,n,o' | |
lopts='disable-javascript,ignore,lowquality,new,old,open' | |
params=$(getopt -o "$shopts" -l "$lopts" -n "$program" -- "$@") || exit 1 | |
eval set -- "$params" | |
# parse options | |
for arg in "$@"; do | |
if (( last == 1 )); then | |
wkargs+=("$arg") | |
else | |
case $arg in | |
-i|--ignore) | |
OPTION_IGNORE=1 | |
;; | |
--new) | |
OPTION_NEW=1 | |
;; | |
--old) | |
OPTION_OLD=1 | |
;; | |
-o|--open) | |
OPTION_OPEN=1 | |
;; | |
--) | |
last=1 | |
;; | |
esac | |
fi | |
done | |
# check whether arguments were supplied | |
if (( ${#wkargs[@]} == 0 )); then | |
echo "$PROGRAM: missing operand" >&2 | |
echo "Try '$PROGRAM --help' for more information." >&2 | |
exit 1 | |
# ensure --new and --old are not combined | |
elif (( OPTION_NEW == 1 )) && (( OPTION_OLD == 1 )); then | |
error "'--new' and '--old' may not be used concurrently" | |
exit 1 | |
# ensure wkhtmltopdf is installed | |
elif [[ -z $DEFAULT ]]; then | |
error "wkhtmltopdf is not installed" | |
exit 1 | |
fi | |
makepdf "${wkargs[@]}" | |
exit "${STATUS:-1}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment