#!/bin/sh # Download subtitles from opensubtitles.org # Based on: https://forum.opensubtitles.org/viewtopic.php?f=8&t=16453#p39771 # Dependencies: grep, curl, hexdump, jq, mktemp, tr, tput, gzip usage="usage: $0 [-e episode] [-i imdbid] [-b moviebytesize] [-h moviehash] [-s season] [-l sublanguageid] [-t tag] [-r results] [-c (no cut)] [-d (non-interactive)] [query]" tmpfile=$(mktemp /tmp/subdl-XXXXXX) trap 'rm "$tmpfile"' 0 1 15 urlencode() { printf "%s" "$1" | tr '[:upper:]' '[:lower:]' | \ printf "%%%s" $(hexdump -v -e '/1 "%20x\n"') # Do NOT quote! } checknum() { echo "$1" | grep '^[0-9]\+$' > /dev/null || { echo season, episode, results and bytesize must be natural numbers. exit 1 } } checklang() { echo "$1" | grep '^[a-z]\{3\}\(,[a-z]\{3\}\)*$' > /dev/null || { echo language code must be 3 letters. echo multiple languages are separated with comma. exit 1 } } checkhash() { if [ -z "$moviebytesize" ] || echo "$1" | grep -v '^[[:alnum:]]\{16\}$' > /dev/null then echo hash must have 16 characters. echo hash must be set after moviebytesize. exit 1 fi } checkimdbid() { echo "$1" | grep '^[0-9]\{7\}$' > /dev/null || { echo imdbid must be 7 figures echo imdbid should exclude property prefix exit 1 } } while getopts r:cde:i:b:h:s:l:t: opt do case $opt in r) rows="$OPTARG" ;; c) cols="0" ;; d) dontask="1" ;; e) checknum "$OPTARG" episode="$OPTARG" ;; i) checkimdbid "$OPTARG" imdbid="$OPTARG" ;; b) checknum "$OPTARG" moviebytesize="$OPTARG" ;; h) checkhash "$OPTARG" moviehash="$OPTARG" ;; s) checknum "$OPTARG" season="$OPTARG" ;; l) checklang "$OPTARG" sublanguageid="$OPTARG" ;; t) tag=$(urlencode "$OPTARG") ;; \?) echo "$usage" ; exit 1 ;; esac done shift $(( OPTIND - 1 )) if [ -n "$1" ] && [ -z "$query" ] then query=$(urlencode "$*") elif [ -z "$1" ] && [ "$OPTIND" -eq 1 ] then echo "$usage" exit 1 fi if [ -z "$rows" ] then rows=$(( $(tput lines) - 2 )) [ "$rows" -lt 4 ] && rows=4 elif echo "$1" | grep -v '^[0-9]\+$' > /dev/null then checknum "$rows" [ "$rows" -eq 0 ] && { echo results must be greater than zero. exit 1 } fi [ -z "$cols" ] && cols=$(tput cols) curl -s -S -A 'TemporaryUserAgent' "https://rest.opensubtitles.org/search\ ${episode:+/episode-}${episode}\ ${imdbid:+/imdbid-}${imdbid}\ ${moviebytesize:+/moviebytesize-}${moviebytesize}\ ${moviehash:+/moviehash-}${moviehash}\ ${query:+/query-}${query}\ ${season:+/season-}${season}\ ${sublanguageid:+/sublanguageid-}${sublanguageid}\ ${tag:+/tag-}${tag}" > "$tmpfile" [ -z "$dontask" ] && { jq -e -j -M --argjson rows "$rows" --argjson cols "$cols" ' del(.[$rows:]) | if length == 0 then "no result.\n" | halt_error(1) else [[range(length) | tostring] , [.[].SubFileName]] | transpose | .[] | " " + .[0] + ": " + .[1] | if $cols != 0 then .[:$cols] | . + "\n" else . + "\n" end end' "$tmpfile" || exit 1 printf "Subtitle number: " read -r nu } [ -z "$nu" ] && nu=0 checknum "$nu" dlurl=$(jq -j -M --argjson nu "$nu" '.[$nu].SubDownloadLink' "$tmpfile") filename=$(jq -j -M --argjson nu "$nu" '.[$nu].SubFileName' "$tmpfile") curl -s -S "$dlurl" | gzip -d > "$filename" && echo Done!