|
- #!/usr/bin/env bash
-
- ##########################################################################
- # The MIT License
- #
- # Copyright (c) jomo
- #
- # Permission is hereby granted, free of charge,
- # to any person obtaining a copy of this software and
- # associated documentation files (the "Software"), to
- # deal in the Software without restriction, including
- # without limitation the rights to use, copy, modify,
- # merge, publish, distribute, sublicense, and/or sell
- # copies of the Software, and to permit persons to whom
- # the Software is furnished to do so,
- # subject to the following conditions:
- #
- # The above copyright notice and this permission notice
- # shall be included in all copies or substantial portions of the Software.
- #
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- # ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- ##########################################################################
-
- # https://github.com/jomo/imgur-screenshot
- # https://imgur.com/tools
- #
- # Slightly modified for `nnn` integration
- #
- # Shell: bash
- # Description: Upload an image file to imgur
-
- if [ "${1}" = "--debug" ]; then
- echo "########################################"
- echo "Enabling debug mode"
- echo "Please remove credentials before pasting"
- echo "########################################"
- echo ""
- uname -a
- for arg in ${0} "${@}"; do
- echo -n "'${arg}' "
- done
- echo -e "\n"
- shift
- set -x
- fi
-
- current_version="v1.7.4"
-
- function is_mac() {
- uname | grep -q "Darwin"
- }
-
- ### IMGUR-SCREENSHOT DEFAULT CONFIG ####
-
- # You can override the config in ~/.config/imgur-screenshot/settings.conf
-
- imgur_anon_id="ea6c0ef2987808e"
- imgur_icon_path="${HOME}/Pictures/imgur.png"
-
- imgur_acct_key=""
- imgur_secret=""
- login="false"
- album_title=""
- album_id=""
- credentials_file="${HOME}/.config/imgur-screenshot/credentials.conf"
-
- file_name_format="imgur-%Y_%m_%d-%H:%M:%S.png" # when using scrot, must end with .png!
- file_dir="${HOME}/Pictures"
-
- upload_connect_timeout="5"
- upload_timeout="120"
- upload_retries="1"
-
- # shellcheck disable=SC2034
- if is_mac; then
- screenshot_select_command="screencapture -i %img"
- screenshot_window_command="screencapture -iWa %img"
- screenshot_full_command="screencapture %img"
- open_command="open %url"
- else
- screenshot_select_command="scrot -s %img"
- screenshot_window_command="scrot %img"
- screenshot_full_command="scrot %img"
- open_command="xdg-open %url"
- fi
- open="true"
-
- mode="select"
- edit_command="gimp %img"
- edit="false"
- exit_on_album_creation_fail="true"
-
- log_file="${HOME}/.imgur-screenshot.log"
-
- auto_delete=""
- copy_url="true"
- keep_file="true"
- check_update="true"
-
- # NOTICE: if you make changes here, also edit the docs at
- # https://github.com/jomo/imgur-screenshot/wiki/Config
-
- # You can override the config in ~/.config/imgur-screenshot/settings.conf
-
- ############## END CONFIG ##############
-
- settings_path="${HOME}/.config/imgur-screenshot/settings.conf"
- if [ -f "${settings_path}" ]; then
- source "${settings_path}"
- fi
-
- # dependency check
- if [ "${1}" = "--check" ]; then
- (which grep &>/dev/null && echo "OK: found grep") || echo "ERROR: grep not found"
- if is_mac; then
- if which growlnotify &>/dev/null; then
- echo "OK: found growlnotify"
- elif which terminal-notifier &>/dev/null; then
- echo "OK: found terminal-notifier"
- else
- echo "ERROR: growlnotify nor terminal-notifier found"
- fi
- (which screencapture &>/dev/null && echo "OK: found screencapture") || echo "ERROR: screencapture not found"
- (which pbcopy &>/dev/null && echo "OK: found pbcopy") || echo "ERROR: pbcopy not found"
- else
- (which notify-send &>/dev/null && echo "OK: found notify-send") || echo "ERROR: notify-send (from libnotify-bin) not found"
- (which scrot &>/dev/null && echo "OK: found scrot") || echo "ERROR: scrot not found"
- (which xclip &>/dev/null && echo "OK: found xclip") || echo "ERROR: xclip not found"
- fi
- (which curl &>/dev/null && echo "OK: found curl") || echo "ERROR: curl not found"
- exit 0
- fi
-
-
- # notify <'ok'|'error'> <title> <text>
- function notify() {
- if is_mac; then
- if which growlnotify &>/dev/null; then
- growlnotify --icon "${imgur_icon_path}" --iconpath "${imgur_icon_path}" --title "${2}" --message "${3}"
- else
- terminal-notifier -appIcon "${imgur_icon_path}" -contentImage "${imgur_icon_path}" -title "imgur: ${2}" -message "${3}"
- fi
- else
- if [ "${1}" = "error" ]; then
- notify-send -a ImgurScreenshot -u critical -c "im.error" -i "${imgur_icon_path}" -t 500 "imgur: ${2}" "${3}"
- else
- notify-send -a ImgurScreenshot -u low -c "transfer.complete" -i "${imgur_icon_path}" -t 500 "imgur: ${2}" "${3}"
- fi
- fi
- }
-
- function take_screenshot() {
- echo "Please select area"
- is_mac || sleep 0.1 # https://bbs.archlinux.org/viewtopic.php?pid=1246173#p1246173
-
- cmd="screenshot_${mode}_command"
- cmd=${!cmd//\%img/${1}}
-
- if ! shot_err="$(${cmd} &>/dev/null)"; then #takes a screenshot with selection
- echo "Failed to take screenshot '${1}': '${shot_err}'. For more information visit https://github.com/jomo/imgur-screenshot/wiki/Troubleshooting" | tee -a "${log_file}"
- notify error "Something went wrong :(" "Information has been logged"
- exit 1
- fi
- }
-
- function check_for_update() {
- # exit non-zero on HTTP error, output only the body (no stats) but output errors, follow redirects, output everything to stdout
- remote_version="$(curl --compressed -fsSL --stderr - "https://api.github.com/repos/jomo/imgur-screenshot/releases" | grep -Em 1 --color 'tag_name":\s*".*"' | cut -d '"' -f 4)"
- if [ -n "$remote_version" ]; then
- if [ ! "${current_version}" = "${remote_version}" ] && [ -n "${current_version}" ] && [ -n "${remote_version}" ]; then
- echo "Update found!"
- echo "Version ${remote_version} is available (You have ${current_version})"
- notify ok "Update found" "Version ${remote_version} is available (You have ${current_version}). https://github.com/jomo/imgur-screenshot"
- echo "Check https://github.com/jomo/imgur-screenshot/releases/${remote_version} for more info."
- elif [ -z "${current_version}" ] || [ -z "${remote_version}" ]; then
- echo "Invalid empty version string"
- echo "Current (local) version: '${current_version}'"
- echo "Latest (remote) version: '${remote_version}'"
- else
- echo "Version ${current_version} is up to date."
- fi
- else
- echo "Failed to check for latest version: ${remote_version}"
- fi
- }
-
- function check_oauth2_client_secrets() {
- if [ -z "${imgur_acct_key}" ] || [ -z "${imgur_secret}" ]; then
- echo "In order to upload to your account, register a new application at:"
- echo "https://api.imgur.com/oauth2/addclient"
- echo "Select 'OAuth 2 authorization without a callback URL'"
- echo "Then, set the imgur_acct_key (Client ID) and imgur_secret in your config."
- exit 1
- fi
- }
-
- function load_access_token() {
- token_expire_time=0
- # check for saved access_token and its expiration date
- if [ -f "${credentials_file}" ]; then
- source "${credentials_file}"
- fi
- current_time="$(date +%s)"
- preemptive_refresh_time="$((10*60))"
- expired="$((current_time > (token_expire_time - preemptive_refresh_time)))"
- if [ -n "${refresh_token}" ]; then
- # token already set
- if [ "${expired}" -eq "0" ]; then
- # token expired
- refresh_access_token "${credentials_file}"
- fi
- else
- acquire_access_token "${credentials_file}"
- fi
- }
-
- function acquire_access_token() {
- check_oauth2_client_secrets
- # prompt for a PIN
- authorize_url="https://api.imgur.com/oauth2/authorize?client_id=${imgur_acct_key}&response_type=pin"
- echo "Go to"
- echo "${authorize_url}"
- echo "and grant access to this application."
- read -rp "Enter the PIN: " imgur_pin
-
- if [ -z "${imgur_pin}" ]; then
- echo "PIN not entered, exiting"
- exit 1
- fi
-
- # exchange the PIN for access token and refresh token
- response="$(curl --compressed -fsSL --stderr - \
- -F "client_id=${imgur_acct_key}" \
- -F "client_secret=${imgur_secret}" \
- -F "grant_type=pin" \
- -F "pin=${imgur_pin}" \
- https://api.imgur.com/oauth2/token)"
- save_access_token "${response}" "${1}"
- }
-
- function refresh_access_token() {
- check_oauth2_client_secrets
- token_url="https://api.imgur.com/oauth2/token"
- # exchange the refresh token for access_token and refresh_token
- if ! response="$(curl --compressed -fsSL --stderr - \
- -F "client_id=${imgur_acct_key}" \
- -F "client_secret=${imgur_secret}" \
- -F "grant_type=refresh_token" \
- -F "refresh_token=${refresh_token}" \
- "${token_url}"
- )"; then
- # curl failed
- handle_upload_error "${response}" "${token_url}"
- exit 1
- fi
- save_access_token "${response}" "${1}"
- }
-
- function save_access_token() {
- if ! grep -q "access_token" <<<"${1}"; then
- # server did not send access_token
- echo "Error: Something is wrong with your credentials:"
- echo "${1}"
- exit 1
- fi
-
- access_token="$(grep -Eo 'access_token":".*"' <<<"${1}" | cut -d '"' -f 3)"
- refresh_token="$(grep -Eo 'refresh_token":".*"' <<<"${1}" | cut -d '"' -f 3)"
- expires_in="$(grep -Eo 'expires_in":[0-9]*' <<<"${1}" | cut -d ':' -f 2)"
- token_expire_time="$(( $(date +%s) + expires_in ))"
-
- # create dir if not exist
- mkdir -p "$(dirname "${2}")" 2>/dev/null
- touch "${2}" && chmod 600 "${2}"
- cat <<EOF > "${2}"
- access_token="${access_token}"
- refresh_token="${refresh_token}"
- token_expire_time="${token_expire_time}"
- EOF
- }
-
- function fetch_account_info() {
- response="$(curl --compressed --connect-timeout "${upload_connect_timeout}" -m "${upload_timeout}" --retry "${upload_retries}" -fsSL --stderr - -H "Authorization: Bearer ${access_token}" https://api.imgur.com/3/account/me)"
- if grep -Eq '"success":\s*true' <<<"${response}"; then
- username="$(grep -Eo '"url":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4)"
- echo "Logged in as ${username}."
- echo "https://${username}.imgur.com"
- else
- echo "Failed to fetch info: ${response}"
- fi
- }
-
- function delete_image() {
- response="$(curl --compressed -X DELETE -fsSL --stderr - -H "Authorization: Client-ID ${1}" "https://api.imgur.com/3/image/${2}")"
- if grep -Eq '"success":\s*true' <<<"${response}"; then
- echo "Image successfully deleted (delete hash: ${2})." >> "${3}"
- else
- echo "The Image could not be deleted: ${response}." >> "${3}"
- fi
- }
-
- function upload_authenticated_image() {
- echo "Uploading '${1}'..."
- title="$(echo "${1}" | rev | cut -d "/" -f 1 | cut -d "." -f 2- | rev)"
- if [ -n "${album_id}" ]; then
- response="$(curl --compressed --connect-timeout "${upload_connect_timeout}" -m "${upload_timeout}" --retry "${upload_retries}" -fsSL --stderr - -F "title=${title}" -F "image=@\"${1}\"" -F "album=${album_id}" -H "Authorization: Bearer ${access_token}" https://api.imgur.com/3/image)"
- else
- response="$(curl --compressed --connect-timeout "${upload_connect_timeout}" -m "${upload_timeout}" --retry "${upload_retries}" -fsSL --stderr - -F "title=${title}" -F "image=@\"${1}\"" -H "Authorization: Bearer ${access_token}" https://api.imgur.com/3/image)"
- fi
-
- # JSON parser premium edition (not really)
- if grep -Eq '"success":\s*true' <<<"${response}"; then
- img_id="$(grep -Eo '"id":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4)"
- img_ext="$(grep -Eo '"link":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4 | rev | cut -d "." -f 1 | rev)" # "link" itself has ugly '\/' escaping and no https!
- del_id="$(grep -Eo '"deletehash":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4)"
-
- if [ -n "${auto_delete}" ]; then
- export -f delete_image
- echo "Deleting image in ${auto_delete} seconds."
- nohup /bin/bash -c "sleep ${auto_delete} && delete_image ${imgur_anon_id} ${del_id} ${log_file}" &
- fi
-
- handle_upload_success "https://i.imgur.com/${img_id}.${img_ext}" "https://imgur.com/delete/${del_id}" "${1}"
- else # upload failed
- err_msg="$(grep -Eo '"error":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4)"
- test -z "${err_msg}" && err_msg="${response}"
- handle_upload_error "${err_msg}" "${1}"
- fi
- }
-
- function upload_anonymous_image() {
- echo "Uploading '${1}'..."
- title="$(echo "${1}" | rev | cut -d "/" -f 1 | cut -d "." -f 2- | rev)"
- if [ -n "${album_id}" ]; then
- response="$(curl --compressed --connect-timeout "${upload_connect_timeout}" -m "${upload_timeout}" --retry "${upload_retries}" -fsSL --stderr - -H "Authorization: Client-ID ${imgur_anon_id}" -F "title=${title}" -F "image=@\"${1}\"" -F "album=${album_id}" https://api.imgur.com/3/image)"
- else
- response="$(curl --compressed --connect-timeout "${upload_connect_timeout}" -m "${upload_timeout}" --retry "${upload_retries}" -fsSL --stderr - -H "Authorization: Client-ID ${imgur_anon_id}" -F "title=${title}" -F "image=@\"${1}\"" https://api.imgur.com/3/image)"
- fi
- # JSON parser premium edition (not really)
- if grep -Eq '"success":\s*true' <<<"${response}"; then
- img_id="$(grep -Eo '"id":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4)"
- img_ext="$(grep -Eo '"link":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4 | rev | cut -d "." -f 1 | rev)" # "link" itself has ugly '\/' escaping and no https!
- del_id="$(grep -Eo '"deletehash":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4)"
-
- if [ -n "${auto_delete}" ]; then
- export -f delete_image
- echo "Deleting image in ${auto_delete} seconds."
- nohup /bin/bash -c "sleep ${auto_delete} && delete_image ${imgur_anon_id} ${del_id} ${log_file}" &
- fi
-
- handle_upload_success "https://i.imgur.com/${img_id}.${img_ext}" "https://imgur.com/delete/${del_id}" "${1}"
- else # upload failed
- err_msg="$(grep -Eo '"error":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4)"
- test -z "${err_msg}" && err_msg="${response}"
- handle_upload_error "${err_msg}" "${1}"
- fi
- }
-
- function handle_upload_success() {
- echo ""
- echo "image link: ${1}"
- echo "delete link: ${2}"
-
- if [ "${copy_url}" = "true" ] && [ -z "${album_title}" ]; then
- if is_mac; then
- echo -n "${1}" | pbcopy
- else
- echo -n "${1}" | xclip -selection clipboard
- fi
- echo "URL copied to clipboard"
- fi
-
- # print to log file: image link, image location, delete link
- echo -e "${1}\t${3}\t${2}" >> "${log_file}"
-
- notify ok "Upload done!" "${1}"
-
- # if [ ! -z "${open_command}" ] && [ "${open}" = "true" ]; then
- # open_cmd=${open_command//\%url/${1}}
- # open_cmd=${open_cmd//\%img/${2}}
- # echo "Opening '${open_cmd}'"
- # eval "${open_cmd}"
- # fi
- }
-
- function handle_upload_error() {
- error="Upload failed: \"${1}\""
- echo "${error}"
- echo -e "Error\t${2}\t${error}" >> "${log_file}"
- notify error "Upload failed :(" "${1}"
- }
-
- function handle_album_creation_success() {
- echo ""
- echo "Album link: ${1}"
- echo "Delete hash: ${2}"
- echo ""
-
- notify ok "Album created!" "${1}"
-
- if [ "${copy_url}" = "true" ]; then
- if is_mac; then
- echo -n "${1}" | pbcopy
- else
- echo -n "${1}" | xclip -selection clipboard
- fi
- echo "URL copied to clipboard"
- fi
-
- # print to log file: album link, album title, delete hash
- echo -e "${1}\t\"${3}\"\t${2}" >> "${log_file}"
- }
-
- function handle_album_creation_error() {
- error="Album creation failed: \"${1}\""
- echo -e "Error\t${2}\t${error}" >> "${log_file}"
- notify error "Album creation failed :(" "${1}"
- if [ ${exit_on_album_creation_fail} ]; then
- exit 1
- fi
- }
-
- while [ ${#} != 0 ]; do
- case "${1}" in
- -h | --help)
- echo "usage: ${0} [--debug] [-c | --check | -v | -h | -u]"
- echo " ${0} [--debug] [option]... [file]..."
- echo ""
- echo " --debug Enable debugging, must be first option"
- echo " -h, --help Show this help, exit"
- echo " -v, --version Show current version, exit"
- echo " --check Check if all dependencies are installed, exit"
- echo " -c, --connect Show connected imgur account, exit"
- echo " -o, --open <true|false> Override 'open' config"
- echo " -e, --edit <true|false> Override 'edit' config"
- echo " -i, --edit-command <command> Override 'edit_command' config (include '%img'), sets --edit 'true'"
- echo " -l, --login <true|false> Override 'login' config"
- echo " -a, --album <album_title> Create new album and upload there"
- echo " -A, --album-id <album_id> Override 'album_id' config"
- echo " -k, --keep-file <true|false> Override 'keep_file' config"
- echo " -d, --auto-delete <s> Automatically delete image after <s> seconds"
- echo " -u, --update Check for updates, exit"
- echo " file Upload file instead of taking a screenshot"
- exit 0;;
- -v | --version)
- echo "${current_version}"
- exit 0;;
- -s | --select)
- mode="select"
- shift;;
- -w | --window)
- mode="window"
- shift;;
- -f | --full)
- mode="full"
- shift;;
- -o | --open)
- # shellcheck disable=SC2034
- open="${2}"
- shift 2;;
- -e | --edit)
- edit="${2}"
- shift 2;;
- -i | --edit-command)
- edit_command="${2}"
- edit="true"
- shift 2;;
- -l | --login)
- login="${2}"
- shift 2;;
- -c | --connect)
- load_access_token
- fetch_account_info
- exit 0;;
- -a | --album)
- album_title="${2}"
- shift 2;;
- -A | --album-id)
- album_id="${2}"
- shift 2;;
- -k | --keep-file)
- keep_file="${2}"
- shift 2;;
- -d | --auto-delete)
- auto_delete="${2}"
- shift 2;;
- -u | --update)
- check_for_update
- exit 0;;
- *)
- upload_files=("${@}")
- break;;
- esac
- done
-
- if [ "${login}" = "true" ]; then
- # load before changing directory
- load_access_token
- fi
-
-
- if [ -n "${album_title}" ]; then
- if [ "${login}" = "true" ]; then
- response="$(curl -fsSL --stderr - \
- -F "title=${album_title}" \
- -H "Authorization: Bearer ${access_token}" \
- https://api.imgur.com/3/album)"
- else
- response="$(curl -fsSL --stderr - \
- -F "title=${album_title}" \
- -H "Authorization: Client-ID ${imgur_anon_id}" \
- https://api.imgur.com/3/album)"
- fi
- if grep -Eq '"success":\s*true' <<<"${response}"; then # Album creation successful
- echo "Album '${album_title}' successfully created"
- album_id="$(grep -Eo '"id":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4)"
- del_id="$(grep -Eo '"deletehash":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4)"
- handle_album_creation_success "https://imgur.com/a/${album_id}" "${del_id}" "${album_title}"
-
- if [ "${login}" = "false" ]; then
- album_id="${del_id}"
- fi
- else # Album creation failed
- err_msg="$(grep -Eo '"error":\s*"[^"]+"' <<<"${response}" | cut -d "\"" -f 4)"
- test -z "${err_msg}" && err_msg="${response}"
- handle_album_creation_error "${err_msg}" "${album_title}"
- fi
- fi
-
- if [ -z "${upload_files[*]}" ]; then
- upload_files[0]=""
- fi
-
- for upload_file in "${upload_files[@]}"; do
-
- if [ -z "${upload_file}" ]; then
- cd "${file_dir}" || exit 1
-
- # new filename with date
- img_file="$(date +"${file_name_format}")"
- take_screenshot "${img_file}"
- else
- # upload file instead of screenshot
- img_file="${upload_file}"
- fi
-
- # get full path
- #cd "$(dirname "$(realpath "${img_file}")")"
- #img_file="$(realpath "${img_file}")"
-
- # check if file exists
- if ! [ -f "${img_file}" ]; then
- echo "file '${img_file}' doesn't exist !"
- read -r _
- exit 1
- fi
-
- # open image in editor if configured
- if [ "${edit}" = "true" ]; then
- edit_cmd=${edit_command//\%img/${img_file}}
- echo "Opening editor '${edit_cmd}'"
- if ! (eval "${edit_cmd}"); then
- echo "Error for image '${img_file}': command '${edit_cmd}' failed, not uploading. For more information visit https://github.com/jomo/imgur-screenshot/wiki/Troubleshooting" | tee -a "${log_file}"
- notify error "Something went wrong :(" "Information has been logged"
- exit 1
- fi
- fi
-
- if [ "${login}" = "true" ]; then
- upload_authenticated_image "${img_file}"
- else
- upload_anonymous_image "${img_file}"
- fi
-
- # delete file if configured
- if [ "${keep_file}" = "false" ] && [ -z "${1}" ]; then
- echo "Deleting temp file ${file_dir}/${img_file}"
- rm -rf "${img_file}"
- fi
-
- echo ""
- done
-
-
- if [ "${check_update}" = "true" ]; then
- check_for_update
- fi
-
- read -r _
|