THEAARBS tools - linkhandler

Published 12-28-2018 09:17:26

Raw

#!/bin/bash
# Imgur client id
# Required for indirect imgur links
imgurClientId=""

# Temp file directory
tmpDir="/tmp/linkhandler"

# Handlers
imgHandler="feh"
gifHandler="mpv --quiet --loop"
vidHandler="mpv --quiet"
dwnHandler="tsp wget"
bcpHandler="bandcamp-dl"
redHandler="rtv"
browser=$BROWSER

## Templates
imgFiles="png apng jpg jpeg jpe bmp tiff" # Images
imgSites="i.imgur.com/
    \|i.redd.it/
    \|deviantart.com/
    \|tinypic.com/
    \|unsplash.com/photos/
    \|gyazo.com/
    \|prnt.sc/
    "

gifFiles="gif webm"           # Gifs
gifSites="gfycat.com/
    \|giphy.com/
    \|gph.is/
    \|gifbin.com/
    \|clips.twitch.tv/
    \|streamable.com/
    "

vidFiles="mkv mp4 mov mpv flv avi"    # Video
vidSites="youtube.com/watch
    \|youtube.com/embed/
    \|youtube.com/video/
    \|youtu.be/
    \|hooktube.com/
    \|bitchute.com/
    \|vimeo.com/
    \|liveleak.com/
    \|twitch.tv/
    \|neatclip.com/
    "

# Download
dwnFiles="pdf csv doc docx xls xlsx ppt pptx mp3 flac opus ogg aac"
dwnSites="raw.githubusercontent.com/"

bcpSites="bandcamp.com/album/"        # BandCamp

redFiles=""   # Reddit
redSites="reddit.com/"

brwFiles="htm html shtm shtml php asp aspx" # Browser
brwSites="wikipedia.org/
    \|archlinux.org/
    \|wiki.gentoo.org/
    \|twitter.com/
    \|github.com/
    \|stackoverflow.com/
    \|stackexchange.com/
    \|superuser.com/
    "

### Functions
# Usage
usage() {
    cat << EOF
USAGE
   $(basename "$0") [OPTIONS] URLS...

OPTIONS
   -h, --help        Print help and exit.
   -d, --detect      Detect link type instead of opening in browser.
                     (it will then be opened in the appropiate handler)
   -v, --verbose     Print progress as links are being processed.
EOF
}

# Print to stdout if verbose mode is enabled
printMessage() { if [[ -n $verbose ]]; then echo -e "$@" ; fi ;}

# Check dependecies
checkDep() { if ! command -v "$1" > /dev/null ; then echo "$(basename "$0"): \"$1\" isn't installed!" >&2 ; return 1 ; fi ;}

# Determine appropiate handler based on filetype
# Indirect links will usually be opened in the browser,
# unless you add the site to one of the templates above.
detectLinkType() {
    # Download file
    mkdir -p "${tmpDir:-/tmp/linkhandler}"
    tmp="$(mktemp -d "${tmpDir:-/tmp/linkhandler}/XXXXXXXX")/$(basename "$1")"
    checkDep wget && wget -q -O "$tmp" -- "$1"
    # Detect mime type
    case "$(file -b --mime-type "$tmp" 2>/dev/null)" in
        image/gif|video/webm) printMessage "Link type: Gif" ; gifQueue+=( "$tmp" ) ;;
        image/*) printMessage "Link type: Image" ; imgQueue+=( "$tmp" ) ;;
        video/*|audio/*) printMessage "Link type: Video" ; vidQueue+=( "$tmp" ) ;;
        *) printMessage "Link type: Browser" ; brwQueue+=( "$1" ) ;;
    esac ;}

## Send Imgur API request
imgurReq() {
    checkDep curl &&
        curl -s -H "Authorization: Client-ID $imgurClientId" \
              -- "https://api.imgur.com/3/$1/${2##*/}" ;}

# Queue Imgur links into the appropiate handler's queue
# Turns all animated formats into mp4
imgurQueue() {
    # For indirect imgurCheck links
    if [[ $1 == -i ]]; then
        local indirectLink="true"
        unset printNewline
        shift 1
    fi

    for link; do
        [[ -n $indirectLink ]] && printMessage "Link: $link"
        [[ $link =~ \?.+$ ]] && link="${link%\?*}"

        # Gif
        if [[ "${link##*.}" =~ ^(gif|gifv|mov|mp4)$ ]]; then
            printMessage "Link type: Gif"
            [[ -n $indirectLink ]] && printMessage
            gifQueue+=( "${link%.*}.mp4" )

        # Image
        elif [[ "${link##*.}" =~ ^(jpg|jpeg|png|apng|tiff)$  ]]; then
            printMessage "Link type: Image"
            [[ -n $indirectLink ]] && printMessage
            imgQueue+=( "$link" )

        # Indirect link
        else
            printMessage "Link type: Indirect Imgur link. Detecting type..."
            imgurCheckQueue+=( "$link" )
        fi
    done
}

# Determine wether Imgur link is of an album or an image,
# then add it to the respective handler's queue
imgurCheck() {
    for link; do
        # Album
        if imgurReply="$(imgurReq album "$link")" &&
        [[ $(echo "$imgurReply" | jq -j '.status') = 200 ]]; then
            printMessage "Imgur link type: Album\n"
            imgurLinks="$(echo "$imgurReply" | jq -r '.data.images[].link')"
            imgurQueue -i $imgurLinks

        # Single image/gif
        elif imgurReply="$(imgurReq image "$link")" &&
        [[ $(echo "$imgurReply" | jq -j '.status') = 200 ]]; then
            printMessage "Imgur link type: Single image/gif\n"
            imgurLinks="$(echo "$imgurReply" | jq -r '.data.link')"
            imgurQueue -i $imgurLinks

        # Invalid link
        else
            echo "Error: Invalid Imgur link!" >&2
        fi
    done
}


## Flags
[[ $# = 0 ]] && { ${browser:-usage}; exit 0; }
checkDep getopt &&
    eval set -- $(getopt -o "h,d,v" -l "help,detect,verbose" \
                         -n "$(basename "$0")" -- "$@")
while true; do
    case "$1" in
        -h|--help) usage ; exit 0 ;;
        -d|--detect) detect="true" ; shift 1 ;;
        -v|--verbose) verbose="true" ; shift 1 ;;
        --) shift 1 ; break ;;
    esac
done

for arg; do
    printMessage "Link: $arg"
    printNewline="true"
    ext="${arg##*.}"
    if [[ $arg =~ \]\(https?://.+ ]] && checkDep sed    # Embedded markdown link
        then arg="$(echo "$arg" | sed -E 's|.*\]\((https?://.+)|\1|; s|\)$||')" ; fi
    # Imgur image/gif/album
    if [[ $arg =~ imgur\.com/.+ ]]; then
        imgurQueue "$arg"
        # Indirect link
        if [[ -n $imgurCheckQueue ]] && checkDep jq; then
            if [[ -n $imgurClientId ]]
                then imgurCheck ${imgurCheckQueue[@]}
            else
                echo "Error: Imgur client id not set!" >&2
                printMessage "Link type: Browser"
                brwQueue+=( "$arg" )
            fi
        fi
    elif [[ $arg =~ v\.redd\.it/[a-z0-9]+ ]]
        then printMessage "Link type: Gif" ; gifQueue+=( "${arg%/DASHPlaylist.mpd}/DASHPlaylist.mpd" )
    elif echo "$arg" | grep -q "$gifSites" ||
    echo "$gifFiles" | grep -q "${ext%%\?*}"
        then printMessage "Link type: Gif" ; gifQueue+=( "$arg" )
    elif echo "$arg" | grep -q "$imgSites" ||
    echo "$imgFiles" | grep -q "${ext%%\?*}"
        then printMessage "Link type: Image" ; imgQueue+=( "$arg" )
    elif echo "$arg" | grep -q "$vidSites" ||
    echo "$vidFiles" | grep -q "${ext%%\?*}"
        then printMessage "Link type: Video" ; vidQueue+=( "$arg" )
    elif echo "$arg" | grep -q "$dwnSites" ||
    echo "$dwnFiles" | grep -q "${ext%%\?*}"
        then printMessage "Link type: Download" ; dwnQueue+=( "$arg" )
    elif echo "$arg" | grep -q "$bcpSites"
        then printMessage "Link type: Bandcamp" ; bcpQueue+=( "$arg" )
    elif echo "$arg" | grep -q "$redSites"
        then printMessage "Link type: Reddit" ; redQueue+=( "$arg" )
    elif echo "$arg" | grep -q "$brwSites" ||
    echo "$brwFiles" | grep -q "${ext%%\?*}" ||
    [[ -z $detect ]]
        then printMessage "Link type: Browser" ; brwQueue+=( "$arg" )
    else
        printMessage "Detecting link type..."
        detectLinkType "$arg"
    fi
    if [[ -n $printNewline ]]
        then printMessage ; unset printNewline ; fi
done

printMessage "Opening links..."

if [[ -n $imgQueue ]] && checkDep ${imgHandler%%\ *}
    then $imgHandler ${imgQueue[@]} &disown ; fi

if [[ -n $gifQueue ]] && checkDep ${gifHandler%%\ *}
    then $gifHandler ${gifQueue[@]} &disown ; fi

if [[ -n $vidQueue ]] && checkDep ${vidHandler%%\ *}
    then $vidHandler ${vidQueue[@]} &disown ; fi

if [[ -n $dwnQueue ]] && checkDep ${dwnHandler%%\ *}
    then $dwnHandler ${dwnQueue[@]} &disown ; fi

if [[ -n $bcpQueue ]] && checkDep ${bcpHandler%%\ *}
    then cd ~/Downloads ; $bcpHandler ${bcpQueue[@]} >/dev/null &disown ; fi

if [[ -n $redQueue ]] && checkDep ${redHandler%%\ *}
    then $TERMINAL -e $redHandler ${redQueue[@]} &disown ; fi

if [[ -n $brwQueue ]] && checkDep ${browser%%\ *}
    then $browser ${brwQueue[@]} &disown ; fi