├── icons ├── thunar-gpg-info.png ├── thunar-gpg-decrypt.png ├── thunar-gpg-encrypt.png ├── thunar-media-info.pdf ├── thunar-media-info.png ├── thunar-convert-to-jpg.png ├── thunar-convert-to-png.png ├── thunar-paste-to-gist.png ├── thunar-paste-to-pastebin.png ├── thunar-upload-to-imgur.png └── thunar-upload-to-postimage.png ├── .travis.yml ├── LICENSE ├── thunar-convert-to-jpg.sh ├── thunar-convert-to-png.sh ├── thunar-gpg-decrypt.sh ├── thunar-gpg-verify-signature.sh ├── thunar-paste-to-gist.sh ├── thunar-openssl-encrypt-decrypt.sh ├── thunar-paste-to-pastebin.sh ├── thunar-media-info.sh ├── thunar-upload-to-postimage.sh ├── thunar-video-to-gif.sh ├── thunar-upload-to-imgur.sh ├── thunar-gpg-sign.sh ├── thunar-gpg-info.sh ├── thunar-gpg-encrypt.sh └── README.md /icons/thunar-gpg-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cytopia/thunar-custom-actions/HEAD/icons/thunar-gpg-info.png -------------------------------------------------------------------------------- /icons/thunar-gpg-decrypt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cytopia/thunar-custom-actions/HEAD/icons/thunar-gpg-decrypt.png -------------------------------------------------------------------------------- /icons/thunar-gpg-encrypt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cytopia/thunar-custom-actions/HEAD/icons/thunar-gpg-encrypt.png -------------------------------------------------------------------------------- /icons/thunar-media-info.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cytopia/thunar-custom-actions/HEAD/icons/thunar-media-info.pdf -------------------------------------------------------------------------------- /icons/thunar-media-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cytopia/thunar-custom-actions/HEAD/icons/thunar-media-info.png -------------------------------------------------------------------------------- /icons/thunar-convert-to-jpg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cytopia/thunar-custom-actions/HEAD/icons/thunar-convert-to-jpg.png -------------------------------------------------------------------------------- /icons/thunar-convert-to-png.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cytopia/thunar-custom-actions/HEAD/icons/thunar-convert-to-png.png -------------------------------------------------------------------------------- /icons/thunar-paste-to-gist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cytopia/thunar-custom-actions/HEAD/icons/thunar-paste-to-gist.png -------------------------------------------------------------------------------- /icons/thunar-paste-to-pastebin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cytopia/thunar-custom-actions/HEAD/icons/thunar-paste-to-pastebin.png -------------------------------------------------------------------------------- /icons/thunar-upload-to-imgur.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cytopia/thunar-custom-actions/HEAD/icons/thunar-upload-to-imgur.png -------------------------------------------------------------------------------- /icons/thunar-upload-to-postimage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cytopia/thunar-custom-actions/HEAD/icons/thunar-upload-to-postimage.png -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: sh 2 | 3 | before_script: 4 | - sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu/ trusty-backports restricted main universe" 5 | - sudo apt-get update -qq 6 | - sudo apt-get install -qq shellcheck 7 | 8 | script: 9 | - shellcheck --shell=sh thunar-convert-to-jpg.sh 10 | - shellcheck --shell=sh thunar-convert-to-png.sh 11 | - shellcheck --shell=sh thunar-gpg-decrypt.sh 12 | - shellcheck --shell=sh thunar-gpg-encrypt.sh 13 | - shellcheck --shell=sh thunar-gpg-info.sh 14 | - shellcheck --shell=sh thunar-gpg-sign.sh 15 | - shellcheck --shell=sh thunar-gpg-verify-signature.sh 16 | - shellcheck --shell=sh thunar-media-info.sh 17 | - shellcheck --shell=sh thunar-video-to-gif.sh 18 | - shellcheck --shell=sh thunar-paste-to-gist.sh 19 | - shellcheck --shell=sh thunar-paste-to-pastebin.sh 20 | - shellcheck --shell=bash thunar-upload-to-imgur.sh 21 | - shellcheck --shell=bash thunar-upload-to-postimage.sh 22 | - shellcheck --shell=bash thunar-openssl-encrypt-decrypt.sh 23 | 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 cytopia 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /thunar-convert-to-jpg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Convert an image file to a jpg file. 4 | # 5 | # * Put this file into your home binary dir: ~/bin/ 6 | # * Make it executable: chmod +x 7 | # 8 | # 9 | # Required Software: 10 | # ------------------------- 11 | # * convert 12 | # 13 | # 14 | # Thunar Integration 15 | # ------------------------ 16 | # 17 | # Command: ~/bin/thunar-convert-to-jpg.sh -f %f 18 | # File Pattern: * 19 | # Appear On: Image Files 20 | # 21 | # 22 | # Usage: 23 | # ------------------------- 24 | # thunar-convert-to-jpg.sh -f 25 | # 26 | # required: 27 | # -f input filename 28 | # 29 | # Note: 30 | # ------------------------- 31 | # 32 | # Feel free to adjust/improve and commit back to: 33 | # https://github.com/cytopia/thunar-custom-actions 34 | # 35 | 36 | 37 | usage() { 38 | echo "$0 -f " 39 | echo 40 | echo " required:" 41 | echo " -f input filename" 42 | echo 43 | } 44 | 45 | 46 | while getopts ":f:" i; do 47 | case "${i}" in 48 | f) 49 | f=${OPTARG} 50 | ;; 51 | *) 52 | echo "Error - unrecognized option $1" 1>&2 53 | usage 54 | ;; 55 | esac 56 | done 57 | shift $((OPTIND-1)) 58 | 59 | # Check if file is specified 60 | if [ -z "${f}" ]; then 61 | echo "Error - no file specified" 1>&2 62 | usage 63 | exit 1 64 | fi 65 | 66 | # Check if convert exists 67 | if ! command -v convert >/dev/null 2>&1 ; then 68 | echo "Error - 'convert' not found." 1>&2 69 | exit 1 70 | fi 71 | 72 | $(which convert) "${f}" "${f}.jpg" 73 | exit $? 74 | 75 | -------------------------------------------------------------------------------- /thunar-convert-to-png.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Convert an image file to a png file. 4 | # 5 | # * Put this file into your home binary dir: ~/bin/ 6 | # * Make it executable: chmod +x 7 | # 8 | # 9 | # Required Software: 10 | # ------------------------- 11 | # * convert 12 | # 13 | # 14 | # Thunar Integration 15 | # ------------------------ 16 | # 17 | # Command: ~/bin/thunar-convert-to-png.sh -f %f 18 | # File Pattern: * 19 | # Appear On: Image Files 20 | # 21 | # 22 | # Usage: 23 | # ------------------------- 24 | # thunar-convert-to-png.sh -f 25 | # 26 | # required: 27 | # -f input filename 28 | # 29 | # Note: 30 | # ------------------------- 31 | # 32 | # Feel free to adjust/improve and commit back to: 33 | # https://github.com/cytopia/thunar-custom-actions 34 | # 35 | 36 | 37 | usage() { 38 | echo "$0 -f " 39 | echo 40 | echo " required:" 41 | echo " -f input filename" 42 | echo 43 | } 44 | 45 | 46 | while getopts ":f:" i; do 47 | case "${i}" in 48 | f) 49 | f=${OPTARG} 50 | ;; 51 | *) 52 | echo "Error - unrecognized option $1" 1>&2; 53 | usage 54 | ;; 55 | esac 56 | done 57 | shift $((OPTIND-1)) 58 | 59 | # Check if file is specified 60 | if [ -z "${f}" ]; then 61 | echo "Error - no file specified" 1>&2; 62 | usage 63 | exit 1 64 | fi 65 | 66 | # Check if convert exists 67 | if ! command -v convert >/dev/null 2>&1 ; then 68 | echo "Error - 'convert' not found." 1>&2 69 | exit 1 70 | fi 71 | 72 | $(which convert) "${f}" "${f}.png" 73 | exit $? 74 | 75 | -------------------------------------------------------------------------------- /thunar-gpg-decrypt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Decrypt a gpg encrypted file. 4 | # 5 | # * Put this file into your home binary dir: ~/bin/ 6 | # * Make it executable: chmod +x 7 | # 8 | # 9 | # Required Software: 10 | # ------------------------- 11 | # * gpg 12 | # 13 | # 14 | # Thunar Integration 15 | # ------------------------ 16 | # 17 | # replace urxvtcd with your favorite terminal 18 | # 19 | # Command: urxvtcd -e ~/bin/thunar-gpg-decrypt.sh -f %f 20 | # File Pattern: * 21 | # Appear On: Other Files 22 | # 23 | # 24 | # Usage: 25 | # ------------------------- 26 | # thunar-gpg-decrypt.sh -f 27 | # 28 | # required: 29 | # -f input filename 30 | # 31 | # Note: 32 | # ------------------------- 33 | # 34 | # Feel free to adjust/improve and commit back to: 35 | # https://github.com/cytopia/thunar-custom-actions 36 | # 37 | 38 | 39 | usage() { 40 | echo "$0 -f " 41 | echo 42 | echo " required:" 43 | echo " -f input filename" 44 | echo 45 | } 46 | 47 | 48 | while getopts ":f:" i; do 49 | case "${i}" in 50 | f) 51 | f=${OPTARG} 52 | ;; 53 | *) 54 | echo "Error - unrecognized option $1" 1>&2; 55 | usage 56 | ;; 57 | esac 58 | done 59 | shift $((OPTIND-1)) 60 | 61 | # Check if file is specified 62 | if [ -z "${f}" ]; then 63 | echo "Error - no file specified" 1>&2; 64 | usage 65 | exit 1 66 | fi 67 | 68 | # Check if gpg exists 69 | if ! command -v gpg >/dev/null 2>&1 ; then 70 | echo "Error - 'gpg' not found." 1>&2 71 | exit 1 72 | fi 73 | 74 | 75 | # remove ".gpg" file extension if it exists 76 | output="$( echo "${f}" | sed 's/\.gpg$//g' )" 77 | 78 | $(which gpg) -o "${output}" -d "${f}" 79 | exit $? 80 | 81 | -------------------------------------------------------------------------------- /thunar-gpg-verify-signature.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Verify the gpg signature of *.asc or *.sig files. 4 | # 5 | # * Put this file into your home binary dir: ~/bin/ 6 | # * Make it executable: chmod +x 7 | # 8 | # 9 | # Required Software: 10 | # ------------------------- 11 | # * gpg 12 | # * zenity 13 | # 14 | # 15 | # Thunar Integration 16 | # ------------------------ 17 | # 18 | # Command: ~/bin/thunar-gpg-verify-signature.sh -f %f 19 | # File Pattern: * 20 | # Appear On: Other Files 21 | # 22 | # 23 | # Usage: 24 | # ------------------------- 25 | # thunar-gpg-verify-signature.sh -f 26 | # 27 | # required: 28 | # -f input filename 29 | # 30 | # Note: 31 | # ------------------------- 32 | # 33 | # Feel free to adjust/improve and commit back to: 34 | # https://github.com/cytopia/thunar-custom-actions 35 | # 36 | 37 | 38 | usage() { 39 | echo "$0 -f " 40 | echo 41 | echo " required:" 42 | echo " -f input filename" 43 | echo 44 | } 45 | 46 | 47 | while getopts ":f:" i; do 48 | case "${i}" in 49 | f) 50 | f=${OPTARG} 51 | ;; 52 | *) 53 | echo "Error - unrecognized option $1" 1>&2; 54 | usage 55 | ;; 56 | esac 57 | done 58 | shift $((OPTIND-1)) 59 | 60 | # Check if file is specified 61 | if [ -z "${f}" ]; then 62 | echo "Error - no file specified" 1>&2; 63 | usage 64 | exit 1 65 | fi 66 | 67 | # Check if gpg exists 68 | if ! command -v gpg >/dev/null 2>&1 ; then 69 | echo "Error - 'gpg' not found." 1>&2 70 | exit 1 71 | fi 72 | 73 | # Check if zenity exists 74 | if ! command -v zenity >/dev/null 2>&1 ; then 75 | echo "Error - 'zenity' not found." 1>&2 76 | exit 1 77 | fi 78 | 79 | 80 | verify() { 81 | output="$(gpg --keyid-format 0xlong --verify "${f}" 2>&1)" 82 | error=$? 83 | echo "${output}" 84 | return $error 85 | } 86 | 87 | 88 | output="$(verify "${f}")" 89 | error=$? 90 | 91 | if [ "$error" -eq "0" ]; then 92 | zenity --info --title="GPG Good signature" --no-markup --text="${output}" 93 | exit $? 94 | else 95 | zenity --error --title="GPG Signature Error" --text="Error verifying the signature:\n\n${output}" 96 | exit 1 97 | fi 98 | 99 | -------------------------------------------------------------------------------- /thunar-paste-to-gist.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Paste a file directly to gist. 4 | # 5 | # * Put this file into your home binary dir: ~/bin/ 6 | # * Make it executable: chmod +x 7 | # 8 | # 9 | # Required Software: 10 | # ------------------------- 11 | # * zenity 12 | # * gist 13 | # * xclip 14 | # 15 | # 16 | # Thunar Integration 17 | # ------------------------ 18 | # 19 | # Command: ~/bin/thunar-paste-to-gist.sh -f %f 20 | # File Pattern: * 21 | # Appear On: Text Files 22 | # 23 | # Note: 24 | # ------------------------- 25 | # 26 | # Feel free to adjust/improve and commit back to: 27 | # https://github.com/cytopia/thunar-custom-actions 28 | # 29 | 30 | 31 | usage() { 32 | echo "$0 -f [-w width(int)] [-h height(int)] [-t window-title]" 33 | echo 34 | echo " required:" 35 | echo " -f input filename" 36 | echo 37 | echo " optional:" 38 | echo 39 | echo " -w (gui) width of window (e.g.: -w 800)" 40 | echo " default is 800" 41 | echo 42 | echo " -h (gui) height of window (e.g.: -h 240)" 43 | echo " default is 240" 44 | echo 45 | echo " -t (gui) window title" 46 | echo " default is filename" 47 | echo 48 | } 49 | 50 | 51 | while getopts ":f:cw:h:t:" i; do 52 | case "${i}" in 53 | f) 54 | f=${OPTARG} 55 | ;; 56 | w) 57 | w=${OPTARG} 58 | ;; 59 | h) 60 | h=${OPTARG} 61 | ;; 62 | t) 63 | t=${OPTARG} 64 | ;; 65 | *) 66 | echo "Error - unrecognized option $1" 1>&2; 67 | usage 68 | ;; 69 | esac 70 | done 71 | shift $((OPTIND-1)) 72 | 73 | # Check if file is specified 74 | if [ -z "${f}" ]; then 75 | echo "Error - no file specified" 1>&2; 76 | usage 77 | exit 1 78 | fi 79 | 80 | # Check if zenity exists 81 | if ! command -v zenity >/dev/null 2>&1 ; then 82 | echo "Error - 'zenity' not found." 1>&2 83 | exit 1 84 | fi 85 | 86 | # Check if zenity exists 87 | if ! command -v gist >/dev/null 2>&1 ; then 88 | echo "Error - 'gist' not found." 1>&2 89 | exit 1 90 | fi 91 | 92 | # Check if zenity exists 93 | if ! command -v xclip >/dev/null 2>&1 ; then 94 | echo "Error - 'xclip' not found." 1>&2 95 | exit 1 96 | fi 97 | 98 | 99 | 100 | ########################## gui output ############################### 101 | [ ! -z "${w##*[!0-9]*}" ] && WIDTH=$w || WIDTH=600 102 | [ ! -z "${h##*[!0-9]*}" ] && HEIGHT=$h || HEIGHT=240 103 | [ -n "${t}" ] && TITLE=$t || TITLE="Pasting to gist: $(basename "${f}")" 104 | 105 | 106 | gist-paste --private --shorten --copy "${f}" \ 107 | | zenity --width=${WIDTH} --height=${HEIGHT} --text-info --title "${TITLE}" 108 | exit $? 109 | -------------------------------------------------------------------------------- /thunar-openssl-encrypt-decrypt.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Symmetric encryption and decryption using openssl. 4 | # 5 | # * Put this file into your home binary dir: ~/bin/ 6 | # * Make it executable: chmod +x 7 | # 8 | # 9 | # Required Software: 10 | # ------------------------- 11 | # * openssl 12 | # * zenity 13 | # 14 | # 15 | # Thunar Integration 16 | # ------------------------ 17 | # 18 | # Command: ~/bin/thunar-openssl-encrypt-decrypt.sh -f %f 19 | # File Pattern: * 20 | # Appear On: Select everything 21 | # 22 | # 23 | # Usage: 24 | # ------------------------- 25 | # thunar-openssl-encrypt-decrypt.sh -f 26 | # 27 | # required: 28 | # -f input filename 29 | # 30 | # Note: 31 | # ------------------------- 32 | # 33 | # Feel free to adjust/improve and commit back to: 34 | # https://github.com/cytopia/thunar-custom-actions 35 | # 36 | 37 | 38 | usage() { 39 | echo "$0 -f " 40 | echo 41 | echo " required:" 42 | echo " -f input filename" 43 | echo 44 | } 45 | 46 | 47 | while getopts ":f:" i; do 48 | case "${i}" in 49 | f) 50 | f=${OPTARG} 51 | ;; 52 | *) 53 | echo "Error - unrecognized option $1" 1>&2; 54 | usage 55 | ;; 56 | esac 57 | done 58 | shift $((OPTIND-1)) 59 | 60 | # Check if file is specified 61 | if [ -z "${f}" ]; then 62 | echo "Error - no file specified" 1>&2; 63 | usage 64 | exit 1 65 | fi 66 | 67 | # Check if gpg exists 68 | if ! command -v openssl >/dev/null 2>&1 ; then 69 | echo "Error - 'gpg' not found." 1>&2 70 | exit 1 71 | fi 72 | 73 | # Check if zenity exists 74 | if ! command -v zenity >/dev/null 2>&1 ; then 75 | echo "Error - 'zenity' not found." 1>&2 76 | exit 1 77 | fi 78 | 79 | 80 | chooseOptions () { 81 | algorithms=$(openssl enc -ciphers 2>&1 \ 82 | | grep '^-' \ 83 | | xargs \ 84 | | sed -e 's/^-//' -e 's/ -/|/g') 85 | 86 | CMD="zenity --forms \ 87 | --title=\"Encryption/Decryption with OpenSSL\" \ 88 | --separator=\"|\" \ 89 | --add-combo=\"Action\" \ 90 | --combo-values=\"Encrypt|Decrypt\" \ 91 | --add-combo=\"Algorithm\" \ 92 | --combo-values=\"${algorithms}\" \ 93 | --add-password=\"key\"" 94 | 95 | eval "${CMD}" 96 | } 97 | 98 | 99 | IFS="|" read -ra options <<< "$(chooseOptions)" 100 | 101 | if [ -z "${options[0]}" ]; then 102 | zenity --error --text="No action to perform." 103 | exit 1 104 | elif [ -z "${options[1]}" ]; then 105 | zenity --error --text="No algorithm." 106 | exit 1 107 | elif [ -z "${options[2]}" ]; then 108 | zenity --error --text="No passphrase." 109 | exit 1 110 | fi 111 | 112 | cmd_option="" 113 | extension=".out" 114 | 115 | case ${options[0]} in 116 | "Encrypt" ) cmd_option="-e" ; extension=".enc" 117 | ;; 118 | "Decrypt" ) cmd_option="-d" ; extension=".dec" 119 | ;; 120 | esac 121 | 122 | alg="-${options[1]}" 123 | 124 | error="$(openssl enc ${cmd_option} "${alg}" -md sha1 -k "${options[2]}" -in "${f}" -out "${f}${extension}" 2>&1)" 125 | errno=$? 126 | 127 | if [ "$errno" -gt "0" ]; then 128 | zenity --error --text="${error}\nreturn code: ${errno}" 129 | exit 1 130 | else 131 | zenity --info --text="${options[0]}ed." 132 | exit $? 133 | fi 134 | -------------------------------------------------------------------------------- /thunar-paste-to-pastebin.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Considering not to use the built-in pastebin api, 5 | # because it is limit, but rather POST to the real site 6 | # and see what regex can do to get all the infos. 7 | # 8 | 9 | 10 | # Feel free to adjust 11 | USERAGENT="Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6" 12 | 13 | # Pastebin API 14 | # @see http://pastebin.com/api 15 | 16 | # TODO: 17 | # would be nice to have an array of keys to choose from 18 | # Or maybe pastebin is giving an official key to this tool 19 | # For now, this is a random generated key that I am not using. 20 | #PB_API_KEY="1cc4d307b5a37854434f262ea6f4aaac" 21 | PB_API_KEY="45472181634ec09cafed2341da212cd3" 22 | 23 | # Required stuff 24 | PB_API_URL="http://pastebin.com/api/api_post.php" 25 | PB_API_OPT="paste" 26 | 27 | # The string being pasted 28 | PB_API_PASTE="" 29 | 30 | # TODO: 31 | # autodetect based on file extension of file being pasted 32 | PB_API_FORMAT="text" 33 | 34 | 35 | 36 | get_api_format() { 37 | file="$1" 38 | default="text" 39 | type="$(file "${file}")" 40 | 41 | # Add all file types here 42 | # @see http://pastebin.com/api#5 43 | case $type in 44 | *POSIX*shell* | *bash*script*) 45 | echo "bash" 46 | ;; 47 | *PHP*script*) 48 | echo "php" 49 | ;; 50 | *) 51 | echo "${default}" 52 | ;; 53 | esac 54 | } 55 | 56 | usage() { 57 | echo "$0 -f [-w width(int)] [-h height(int)] [-t window-title]" 58 | echo 59 | echo " required:" 60 | echo " -f input filename" 61 | echo 62 | echo " optional:" 63 | echo " -w (gui) width of window (e.g.: -w 800)" 64 | echo " default is 800" 65 | echo 66 | echo " -h (gui) height of window (e.g.: -h 240)" 67 | echo " default is 240" 68 | echo 69 | echo " -t (gui) window title" 70 | echo " default is filename" 71 | echo 72 | } 73 | 74 | 75 | while getopts ":f:cw:h:t:" i; do 76 | case "${i}" in 77 | f) 78 | f="${OPTARG}" 79 | ;; 80 | w) 81 | w="${OPTARG}" 82 | ;; 83 | h) 84 | h="${OPTARG}" 85 | ;; 86 | t) 87 | t="${OPTARG}" 88 | ;; 89 | *) 90 | echo "Error - unrecognized option $1" 1>&2; 91 | usage 92 | ;; 93 | esac 94 | done 95 | shift $((OPTIND-1)) 96 | 97 | # Check if file is specified 98 | if [ -z "${f}" ]; then 99 | echo "Error - no file specified" 1>&2; 100 | usage 101 | exit 1 102 | fi 103 | 104 | # Check if zenity exists 105 | if ! command -v zenity >/dev/null 2>&1 ; then 106 | echo "Error - 'zenity' not found." 1>&2 107 | exit 1 108 | fi 109 | 110 | # Check if curl exists 111 | if ! command -v curl >/dev/null 2>&1 ; then 112 | echo "Error - 'curl' not found." 1>&2 113 | exit 1 114 | fi 115 | 116 | [ ! -z "${w##*[!0-9]*}" ] && WIDTH=$w || WIDTH=350 117 | [ ! -z "${h##*[!0-9]*}" ] && HEIGHT=$h || HEIGHT=140 118 | [ -n "${t}" ] && TITLE="${t}" || TITLE="Pastebin: $(basename "${f}")" 119 | 120 | # Read in the file 121 | PB_API_PASTE="$(cat "${f}")" 122 | 123 | # Figure out the correct format for syntax highlighting via `file` 124 | PB_API_FORMAT="$(get_api_format "${f}")" 125 | 126 | 127 | # The output will only contain the url or an error if something went wrong 128 | ZTEXT="$($(which curl) --silent --show-error --user-agent "${USERAGENT}" --data api_option=${PB_API_OPT} --data api_paste_format="${PB_API_FORMAT}" --data api_dev_key=${PB_API_KEY} --data-urlencode api_paste_code="\"${PB_API_PASTE}\"" $PB_API_URL)" 129 | 130 | zenity --width=${WIDTH} --height=${HEIGHT} --info --title "${TITLE}" --text="${ZTEXT}" 131 | exit 132 | 133 | -------------------------------------------------------------------------------- /thunar-media-info.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Get media information about audio/video files. 4 | # 5 | # * Put this file into your home binary dir: ~/bin/ 6 | # * Make it executable: chmod +x 7 | # 8 | # 9 | # Required Software: 10 | # ------------------------- 11 | # * zenity (for gui mode - default) 12 | # * ffmpeg 13 | # 14 | # 15 | # Thunar Integration 16 | # ------------------------ 17 | # 18 | # Command: ~/bin/thunar-media-info.sh -f %f -t %n 19 | # File Pattern: * 20 | # Appear On: Audio Files, Video Files 21 | # 22 | # 23 | # Usage: 24 | # ------------------------- 25 | # thunar-media-info.sh -f [-c] [-w width(int)] [-h height(int)] [-t window-title] 26 | # 27 | # required: 28 | # -f input filename 29 | # 30 | # optional: 31 | # -c no-gui, show console output (zenity not required) 32 | # default is to show gui 33 | # 34 | # -w (gui) width of window (e.g.: -w 800) 35 | # default is 800 36 | # 37 | # -h (gui) height of window (e.g.: -h 240) 38 | # default is 240 39 | # 40 | # -t (gui) window title 41 | # default is filename 42 | # 43 | # Note: 44 | # ------------------------- 45 | # 46 | # Feel free to adjust/improve and commit back to: 47 | # https://github.com/cytopia/thunar-custom-actions 48 | # 49 | 50 | 51 | usage() { 52 | echo "$0 -f [-c] [-w width(int)] [-h height(int)] [-t window-title]" 53 | echo 54 | echo " required:" 55 | echo " -f input filename" 56 | echo 57 | echo " optional:" 58 | echo " -c no-gui, show console output (zenity not required)" 59 | echo " default is to show gui" 60 | echo 61 | echo " -w (gui) width of window (e.g.: -w 800)" 62 | echo " default is 800" 63 | echo 64 | echo " -h (gui) height of window (e.g.: -h 240)" 65 | echo " default is 240" 66 | echo 67 | echo " -t (gui) window title" 68 | echo " default is filename" 69 | echo 70 | exit 1 71 | } 72 | 73 | 74 | while getopts ":f:cw:h:t:" i; do 75 | case "${i}" in 76 | f) 77 | f=${OPTARG} 78 | ;; 79 | c) 80 | c=yes 81 | ;; 82 | w) 83 | w=${OPTARG} 84 | ;; 85 | h) 86 | h=${OPTARG} 87 | ;; 88 | t) 89 | t=${OPTARG} 90 | ;; 91 | *) 92 | echo "Error - unrecognized option $1" 1>&2; 93 | usage 94 | ;; 95 | esac 96 | done 97 | shift $((OPTIND-1)) 98 | 99 | # Check if file is specified 100 | if [ -z "${f}" ]; then 101 | echo "Error - no file specified" 1>&2; 102 | usage 103 | fi 104 | 105 | # Check if zenity exists 106 | if ! command -v zenity >/dev/null 2>&1 ; then 107 | echo "Error - 'zenity' not found." 1>&2 108 | exit 1 109 | fi 110 | 111 | # Check if zenity exists 112 | if ! command -v ffmpeg >/dev/null 2>&1 ; then 113 | echo "Error - 'ffmpeg' not found." 1>&2 114 | exit 1 115 | fi 116 | 117 | 118 | ########################## console output ############################### 119 | 120 | # Do we have textbased output? 121 | if [ -n "${c}" ]; then 122 | ffmpeg -i "${f}" 2>&1 \ 123 | | grep -e Stream -e Duration -e Input 124 | exit 0 125 | fi 126 | 127 | 128 | ########################## gui output ############################### 129 | [ ! -z "${w##*[!0-9]*}" ] && WIDTH=$f || WIDTH=800 130 | [ ! -z "${h##*[!0-9]*}" ] && HEIGHT=$f || HEIGHT=240 131 | [ -n "${t}" ] && TITLE=$t || TITLE="Media Info for: $(basename "${f}")" 132 | 133 | 134 | 135 | ffmpeg -i "${f}" 2>&1 \ 136 | | grep -e Stream -e Duration -e Input \ 137 | | zenity --width=${WIDTH} --height=${HEIGHT} --text-info --title "${TITLE}" 138 | 139 | exit 0 140 | 141 | -------------------------------------------------------------------------------- /thunar-upload-to-postimage.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Upload a Picture to postimage. 4 | # 5 | # * Put this file into your home binary dir: ~/bin/ 6 | # * Make it executable: chmod +x 7 | # 8 | # 9 | # Required Software: 10 | # ------------------------- 11 | # * zenity 12 | # * curl 13 | # * gawk 14 | # 15 | # 16 | # Thunar Integration 17 | # ------------------------ 18 | # 19 | # Command: ~/bin/thunar-upload-to-postimage.sh -f %f 20 | # File Pattern: * 21 | # Appear On: Image Files 22 | # 23 | # 24 | # Usage: 25 | # ------------------------- 26 | # thunar-upload-to-postimage.sh -f [-w width(int)] [-h height(int)] [-t window-title] 27 | # 28 | # required: 29 | # -f input filename 30 | # 31 | # optional: 32 | # 33 | # -w (gui) width of window (e.g.: -w 800) 34 | # default is 800 35 | # 36 | # -h (gui) height of window (e.g.: -h 240) 37 | # default is 240 38 | # 39 | # -t (gui) window title 40 | # default is filename 41 | # 42 | # Note: 43 | # ------------------------- 44 | # 45 | # Feel free to adjust/improve and commit back to: 46 | # https://github.com/cytopia/thunar-custom-actions 47 | # 48 | 49 | 50 | usage() { 51 | echo "$0 -f [-w width(int)] [-h height(int)] [-t window-title]" 52 | echo 53 | echo " required:" 54 | echo " -f input filename" 55 | echo 56 | echo " optional:" 57 | echo " -w (gui) width of window (e.g.: -w 800)" 58 | echo " default is 800" 59 | echo 60 | echo " -h (gui) height of window (e.g.: -h 240)" 61 | echo " default is 240" 62 | echo 63 | echo " -t (gui) window title" 64 | echo " default is filename" 65 | echo 66 | } 67 | 68 | 69 | while getopts ":f:cw:h:t:" i; do 70 | case "${i}" in 71 | f) 72 | f="${OPTARG}" 73 | ;; 74 | w) 75 | w="${OPTARG}" 76 | ;; 77 | h) 78 | h="${OPTARG}" 79 | ;; 80 | t) 81 | t="${OPTARG}" 82 | ;; 83 | *) 84 | echo "Error - unrecognized option $1" 1>&2; 85 | usage 86 | ;; 87 | esac 88 | done 89 | shift $((OPTIND-1)) 90 | 91 | # Check if file is specified 92 | if [ -z "${f}" ]; then 93 | echo "Error - no file specified" 1>&2; 94 | usage 95 | exit 1 96 | fi 97 | 98 | # Check if zenity exists 99 | if ! command -v zenity >/dev/null 2>&1 ; then 100 | echo "Error - 'zenity' not found." 1>&2 101 | exit 1 102 | fi 103 | 104 | # Check if curl exists 105 | if ! command -v curl >/dev/null 2>&1 ; then 106 | echo "Error - 'curl' not found." 1>&2 107 | exit 1 108 | fi 109 | 110 | # Check if gawk exists 111 | if ! command -v gawk >/dev/null 2>&1 ; then 112 | echo "Error - 'gawk' not found." 1>&2 113 | exit 1 114 | fi 115 | 116 | TITLE='Uploading to postimage.org...'$(basename "${f}") 117 | 118 | TMPFILE=$(mktemp) 119 | 120 | [ ! -z "${w##*[!0-9]*}" ] && WIDTH=$w || WIDTH=350 121 | [ ! -z "${h##*[!0-9]*}" ] && HEIGHT=$h || HEIGHT=140 122 | [ -n "${t}" ] && TITLE="${t}" || TITLE="Uploading to postimage: $(basename "${f}")" 123 | 124 | curl -# -L -F "upload[]=@${f}" -o "${TMPFILE}" -F "adult=no" http://postimage.org 2>&1 | gawk -v RS='\r' '{print $2; fflush("") }' | zenity --width="${WIDTH}" --height="${HEIGHT}" --progress --title="${TITLE}" --text="${TITLE}" --auto-close --time-remaining 125 | 126 | ########################## gui output ############################### 127 | [ -n "${t}" ] && TITLE=$t || TITLE="Uploaded to postimage: $(basename "${f}")" 128 | 129 | 130 | TEXT=$(cat "${TMPFILE}") 131 | rm "${TMPFILE}" 132 | 133 | #TAG="$(echo "${TEXT}" | grep -Eo '<[a-z_]+>http' | sed -e "s/http//" | sed -e "s///")" 134 | #URL="$(echo "${TEXT}" | grep -Eo 'http[^<]+')" 135 | ZTEXT="$(echo "${TEXT}" | grep -Eo 'http[^<]*' | grep "\[" | cut -d "]" -f1 | head -1)" 136 | 137 | #urls=($URL) 138 | #tags=($TAG) 139 | #for ((i = 0; i < ${#urls[@]}; i++)) 140 | #do 141 | # ZTEXT="$ZTEXT${tags[$i]}' ${urls[$i]}\n" 142 | #done 143 | zenity --width=${WIDTH} --height=${HEIGHT} --info --title "${TITLE}" --text="${ZTEXT}" 144 | exit $? 145 | 146 | -------------------------------------------------------------------------------- /thunar-video-to-gif.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Convert a video file to an animated gif (high quality mode). 4 | # 5 | # * Put this file into your home binary dir: ~/bin/ 6 | # * Make it executable: chmod +x 7 | # 8 | # 9 | # Required Software: 10 | # ------------------------- 11 | # * zenity (for gui mode - default) 12 | # * ffmpeg 13 | # 14 | # 15 | # Thunar Integration 16 | # ------------------------ 17 | # 18 | # Command: ~/bin/thunar-video-to-gif.sh -f %f -t %n 19 | # File Pattern: * 20 | # Appear On: Video Files 21 | # 22 | # 23 | # Usage: 24 | # ------------------------- 25 | # thunar-video-to-gif.sh -f [-c] 26 | # 27 | # required: 28 | # -f input filename 29 | # 30 | # optional: 31 | # -c no-gui, show console output (zenity not required) 32 | # default is to show gui 33 | # 34 | # 35 | # Note: 36 | # ------------------------- 37 | # 38 | # Feel free to adjust/improve and commit back to: 39 | # https://github.com/cytopia/thunar-custom-actions 40 | # 41 | 42 | # Test if argument is an integer. 43 | # 44 | # @param mixed 45 | # @return integer 0: is number | 1: not a number 46 | isint(){ 47 | printf "%d" "${1}" >/dev/null 2>&1 && return 0 || return 1; 48 | } 49 | 50 | 51 | usage() { 52 | echo "$0 -f [-c]" 53 | echo 54 | echo " required:" 55 | echo " -f input filename" 56 | echo 57 | echo " optional:" 58 | echo " -c no-gui, show console output (zenity not required)" 59 | echo " default is to show gui" 60 | echo 61 | exit 1 62 | } 63 | 64 | 65 | # No console output 66 | c="no" 67 | 68 | while getopts ":f:c" i; do 69 | case "${i}" in 70 | f) 71 | f=${OPTARG} 72 | ;; 73 | 74 | # Console output instead of zenity 75 | c) 76 | c="yes" 77 | ;; 78 | *) 79 | echo "Error - unrecognized option $1" 1>&2; 80 | usage 81 | ;; 82 | esac 83 | done 84 | shift $((OPTIND-1)) 85 | 86 | 87 | # Check if file is specified 88 | if [ -z "${f}" ]; then 89 | echo "Error - no file specified" 1>&2; 90 | usage 91 | fi 92 | 93 | # Check for mktemp 94 | if ! command -v mktemp >/dev/null 2>&1 ; then 95 | echo "Error - 'mktemp' not found (requited to build the palette)." 1>&2 96 | exit 1 97 | fi 98 | 99 | # Check if zenity exists (on gui output) 100 | if [ "${c}" != "yes" ]; then 101 | if ! command -v zenity >/dev/null 2>&1 ; then 102 | echo "Error - 'zenity' not found." 1>&2 103 | exit 1 104 | fi 105 | fi 106 | 107 | # Check if ffmpeg exists 108 | if ! command -v ffmpeg >/dev/null 2>&1 ; then 109 | echo "Error - 'ffmpeg' not found." 1>&2 110 | exit 1 111 | fi 112 | 113 | 114 | 115 | ########################## OPTIONS ############################### 116 | 117 | 118 | 119 | # Tmpfile for palette (to produce better quality) 120 | FILE_PALETTE="$(mktemp).png" 121 | 122 | 123 | ########################## console output ############################### 124 | 125 | # Do we have textbased output? 126 | if [ "${c}" = "yes" ]; then 127 | 128 | while true; do 129 | # shellcheck disable=SC2039 130 | read -r -p "Enter output video width in pixel (integer): " VIDEO_WIDTH 131 | 132 | if ! isint "${VIDEO_WIDTH}"; then 133 | echo "Please enter a valid integer" 134 | else 135 | break; 136 | fi 137 | done 138 | 139 | # FFMPEG Filters 140 | FF_FILTERS="fps=15,scale=${VIDEO_WIDTH}:-1:flags=lanczos" 141 | 142 | 143 | ffmpeg -v warning -i "${f}" -vf "${FF_FILTERS},palettegen" -y "${FILE_PALETTE}" 144 | ffmpeg -v warning -i "${f}" -i "${FILE_PALETTE}" -lavfi "${FF_FILTERS} [x]; [x][1:v] paletteuse" -y "${f}.gif" 145 | 146 | 147 | ########################## gui output ############################### 148 | 149 | else 150 | 151 | while true; do 152 | VIDEO_WIDTH="$(zenity --entry --title="Video width" --text="Enter output video width in pixel (integer):")" 153 | 154 | if ! isint "${VIDEO_WIDTH}"; then 155 | zenity --error --text="Not a valid integer" 156 | else 157 | break; 158 | fi 159 | done 160 | 161 | # FFMPEG Filters 162 | FF_FILTERS="fps=15,scale=${VIDEO_WIDTH}:-1:flags=lanczos" 163 | 164 | ffmpeg -v warning -i "${f}" -vf "${FF_FILTERS},palettegen" -y "${FILE_PALETTE}" | zenity --title="Run 1/2" --text="Run 1/2\nCreating palette for better quality" --progress --pulsate 165 | ffmpeg -v warning -i "${f}" -i "${FILE_PALETTE}" -lavfi "${FF_FILTERS} [x]; [x][1:v] paletteuse" -y "${f}.gif" | zenity --title="Run 2/2" --text="Run 2/2\n Converting Video to gif" --progress --pulsate 166 | 167 | fi 168 | 169 | rm "${FILE_PALETTE}" 170 | exit 0 171 | -------------------------------------------------------------------------------- /thunar-upload-to-imgur.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Upload a Picture to imgur. 4 | # 5 | # * Put this file into your home binary dir: ~/bin/ 6 | # * Make it executable: chmod +x 7 | # 8 | # 9 | # Required Software: 10 | # ------------------------- 11 | # * zenity 12 | # * curl 13 | # * gawk 14 | # 15 | # 16 | # Thunar Integration 17 | # ------------------------ 18 | # 19 | # Command: ~/bin/thunar-upload-to-imgur.sh -f %f 20 | # File Pattern: * 21 | # Appear On: Image Files 22 | # 23 | # 24 | # Usage: 25 | # ------------------------- 26 | # thunar-upload-to-imgur.sh -f [-w width(int)] [-h height(int)] [-t window-title] 27 | # 28 | # required: 29 | # -f input filename 30 | # 31 | # optional: 32 | # 33 | # -w (gui) width of window (e.g.: -w 800) 34 | # default is 800 35 | # 36 | # -h (gui) height of window (e.g.: -h 240) 37 | # default is 240 38 | # 39 | # -t (gui) window title 40 | # default is filename 41 | # 42 | # Note: 43 | # ------------------------- 44 | # 45 | # Feel free to adjust/improve and commit back to: 46 | # https://github.com/cytopia/thunar-custom-actions 47 | # 48 | 49 | 50 | usage() { 51 | echo "$0 -f [-w width(int)] [-h height(int)] [-t window-title]" 52 | echo 53 | echo " required:" 54 | echo " -f input filename" 55 | echo 56 | echo " optional:" 57 | echo " -w (gui) width of window (e.g.: -w 800)" 58 | echo " default is 800" 59 | echo 60 | echo " -h (gui) height of window (e.g.: -h 240)" 61 | echo " default is 240" 62 | echo 63 | echo " -t (gui) window title" 64 | echo " default is filename" 65 | echo 66 | } 67 | 68 | 69 | while getopts ":f:cw:h:t:" i; do 70 | case "${i}" in 71 | f) 72 | f="${OPTARG}" 73 | ;; 74 | w) 75 | w="${OPTARG}" 76 | ;; 77 | h) 78 | h="${OPTARG}" 79 | ;; 80 | t) 81 | t="${OPTARG}" 82 | ;; 83 | *) 84 | echo "Error - unrecognized option $1" 1>&2; 85 | usage 86 | ;; 87 | esac 88 | done 89 | shift $((OPTIND-1)) 90 | 91 | # Check if file is specified 92 | if [ -z "${f}" ]; then 93 | echo "Error - no file specified" 1>&2; 94 | usage 95 | exit 1 96 | fi 97 | 98 | # Check if zenity exists 99 | if ! command -v zenity >/dev/null 2>&1 ; then 100 | echo "Error - 'zenity' not found." 1>&2 101 | exit 1 102 | fi 103 | 104 | # Check if curl exists 105 | if ! command -v curl >/dev/null 2>&1 ; then 106 | echo "Error - 'curl' not found." 1>&2 107 | exit 1 108 | fi 109 | 110 | # Check if gawk exists 111 | if ! command -v gawk >/dev/null 2>&1 ; then 112 | echo "Error - 'gawk' not found." 1>&2 113 | exit 1 114 | fi 115 | 116 | TITLE='Uploading to Imgur...'$(basename "${f}") 117 | 118 | IMGUR_CLIENT_ID="3e7a4deb7ac67da" 119 | TMPFILE=$(mktemp) 120 | 121 | [ ! -z "${w##*[!0-9]*}" ] && WIDTH=$w || WIDTH=350 122 | [ ! -z "${h##*[!0-9]*}" ] && HEIGHT=$h || HEIGHT=140 123 | [ -n "${t}" ] && TITLE="${t}" || TITLE="Uploading to imgur: $(basename "${f}")" 124 | 125 | curl -# -F "image"=@"$f" -o "${TMPFILE}" -F title="${TITLE}" -H "Authorization: Client-ID ${IMGUR_CLIENT_ID}" https://api.imgur.com/3/upload.xml 2>&1 | gawk -v RS='\r' '{print $2; fflush("") }' | zenity --width="${WIDTH}" --height="${HEIGHT}" --progress --title="${TITLE}" --text="${TITLE}" --auto-close --time-remaining 126 | #curl -# -F "image"=@"$f" -F "key"="4907fcd89e761c6b07eeb8292d5a9b2a" http://imgur.com/api/upload.xml | grep -Eo "[0-9]{1,3}" | zenity --width=${WIDTH} --height=${HEIGHT} --progress --title="${TITLE}" --text="${TITLE}" --auto-close --time-remaining 127 | #stdbuf -oL tr $'\r' $'\n' | stdbuf -oL grep --line-buffered -Eo '([0-9]+)\.[0-9]%$' | zenity --width=${WIDTH} --height=${HEIGHT} --progress --title="${TITLE}" --text="${TITLE}" --auto-close --time-remaining 128 | 129 | ########################## gui output ############################### 130 | [ -n "${t}" ] && TITLE=$t || TITLE="Uploaded to imgur: $(basename "${f}")" 131 | 132 | 133 | TEXT=$(cat "${TMPFILE}") 134 | rm "${TMPFILE}" 135 | 136 | #TAG="$(echo "${TEXT}" | grep -Eo '<[a-z_]+>http' | sed -e "s/http//" | sed -e "s///")" 137 | #URL="$(echo "${TEXT}" | grep -Eo 'http[^<]+')" 138 | #ZTEXT="" 139 | #urls=($URL) 140 | #tags=($TAG) 141 | 142 | URL="$(echo "${TEXT}" | grep -E -m 1 -o "(.*)" | sed -e 's,.*\([^<]*\).*,\1,g')" 143 | ZTEXT="Direct URL: $URL" 144 | 145 | #for ((i = 0; i < ${#urls[@]}; i++)) 146 | #do 147 | # ZTEXT="$ZTEXT${tags[$i]}' ${urls[$i]}\n" 148 | #done 149 | zenity --width=${WIDTH} --height=${HEIGHT} --info --title "${TITLE}" --text="${ZTEXT}" 150 | exit $? 151 | 152 | -------------------------------------------------------------------------------- /thunar-gpg-sign.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Sign a file using gpg (ascii armored) 4 | # 5 | # * Put this file into your home binary dir: ~/bin/ 6 | # * Make it executable: chmod +x 7 | # 8 | # 9 | # Required Software: 10 | # ------------------------- 11 | # * gpg 12 | # * zenity 13 | # 14 | # 15 | # Thunar Integration 16 | # ------------------------ 17 | # 18 | # Command: ~/bin/thunar-gpg-sign.sh -f %f 19 | # File Pattern: * 20 | # Appear On: Other Files 21 | # 22 | # 23 | # Usage: 24 | # ------------------------- 25 | # thunar-gpg-sign.sh -f 26 | # 27 | # required: 28 | # -f input filename 29 | # 30 | # Note: 31 | # ------------------------- 32 | # 33 | # Feel free to adjust/improve and commit back to: 34 | # https://github.com/cytopia/thunar-custom-actions 35 | # 36 | 37 | 38 | 39 | ################################################################################ 40 | # 41 | # Functions 42 | # 43 | ################################################################################ 44 | 45 | 46 | usage() { 47 | echo "$0 -f " 48 | echo 49 | echo " required:" 50 | echo " -f input filename" 51 | echo 52 | } 53 | 54 | # 55 | # Get email by secret key. 56 | # 57 | # @param string Secret key 58 | # @output string Email 59 | # 60 | getMailBySecKey() { 61 | _sec="$1" 62 | _mail="$(gpg --list-secret-keys | grep -A 1 "${_sec}" | tail -n1 | sed 's/uid[[:space:]]*//g')" 63 | 64 | echo "${_mail}" 65 | } 66 | 67 | 68 | 69 | # 70 | # Display zenity box for choosing your own private keys 71 | # from a list. 72 | # 73 | # @output string Private key string (bits, key, name, email) 74 | # 75 | chooseSecret () { 76 | 77 | seckeys="$(gpg --list-secret-keys \ 78 | | grep -A 1 "^sec" \ 79 | | sed -n -e "s:^sec *\([A-Za-z0-9]\+\)/\([A-F0-9]\+\) .*$:\1 \2:p" -e "s:^uid *\(.*\)$:\"\1\":p" \ 80 | | tr '\n' ' ')" 81 | 82 | 83 | CMD="zenity --list \ 84 | --width=550 --height=250 \ 85 | --title=\"Choose private key...\" \ 86 | --print-column=2 \ 87 | --text=\"Choose your private key\" \ 88 | --column=\"Bit\" --column=\"Key\" --column=\"Secret Key\" ${seckeys}" 89 | 90 | eval "${CMD}" 91 | } 92 | 93 | 94 | # 95 | # Display secure dialog to read in the pasword 96 | # 97 | # @param string My chosen secret key 98 | # @output string My entered password 99 | readPassword () { 100 | _my_key="$1" 101 | _my_mail="$(getMailBySecKey "${_my_key}")" 102 | printf "SETDESC Enter your password for: %s (%s)\nGETPIN\n" "${_my_key}" "${_my_mail}" | ${BIN_PINENTRY} 2> /dev/null | grep "D" | awk '{print $2}' 103 | } 104 | 105 | 106 | sign() { 107 | key="${1}" # email or key 108 | pass="${2}" 109 | f="${3}" 110 | 111 | output="$(gpg --armor --yes --local-user "${key}" --detach-sign --passphrase "${pass}" "${f}" 2>&1)" 112 | error=$? 113 | echo "${output}" 114 | return $error 115 | } 116 | 117 | 118 | 119 | ################################################################################ 120 | # 121 | # Evaluate command line arguments 122 | # 123 | ################################################################################ 124 | 125 | 126 | while getopts ":f:" i; do 127 | case "${i}" in 128 | f) 129 | f=${OPTARG} 130 | ;; 131 | *) 132 | echo "Error - unrecognized option $1" 1>&2; 133 | usage 134 | ;; 135 | esac 136 | done 137 | shift $((OPTIND-1)) 138 | 139 | # Check if file is specified 140 | if [ -z "${f}" ]; then 141 | echo "Error - no file specified" 1>&2; 142 | usage 143 | exit 1 144 | fi 145 | 146 | 147 | 148 | ################################################################################ 149 | # 150 | # Check binary requirements 151 | # 152 | ################################################################################ 153 | 154 | 155 | # Check if gpg exists 156 | if ! command -v gpg >/dev/null 2>&1 ; then 157 | echo "Error - 'gpg' not found." 1>&2 158 | exit 1 159 | fi 160 | 161 | # Check if zenity exists 162 | if ! command -v zenity >/dev/null 2>&1 ; then 163 | echo "Error - 'zenity' not found." 1>&2 164 | exit 1 165 | fi 166 | 167 | # Check if pinentry-gtk-2 exists 168 | BIN_PINENTRY="" 169 | if [ "$(uname)" != "Darwin" ]; then 170 | if ! command -v pinentry-gtk-2 >/dev/null 2>&1 ; then 171 | echo "Error - 'pinentry-gtk-2' not found." 1>&2 172 | exit 1 173 | fi 174 | BIN_PINENTRY="pinentry-gtk-2" 175 | else 176 | if ! command -v pinentry-mac >/dev/null 2>&1 ; then 177 | echo "Error - 'pinentry-mac' not found." 1>&2 178 | exit 1 179 | fi 180 | BIN_PINENTRY="pinentry-mac" 181 | fi 182 | 183 | 184 | ################################################################################ 185 | # 186 | # Main entry point 187 | # 188 | ################################################################################ 189 | 190 | 191 | u="$(chooseSecret)" 192 | if [ -z "${u}" ]; then 193 | zenity --error --text="No Secret key specified." 194 | exit 1 195 | fi 196 | # fix zenity bug on double click 197 | # https://bugzilla.gnome.org/show_bug.cgi?id=698683 198 | u="$(echo "${u}" | awk '{split($0,a,"|"); print a[1]}')" 199 | 200 | p="$(readPassword "${u}")" 201 | if [ -z "${p}" ]; then 202 | zenity --error --text="No Password specified." 203 | exit 1 204 | fi 205 | 206 | 207 | output="$(sign "${u}" "${p}" "${f}")" 208 | error=$? 209 | 210 | if [ "$error" -eq "0" ]; then 211 | zenity --info --title="Signature Created" --no-markup --text="Signature successfully created for ${f}" 212 | exit $? 213 | else 214 | zenity --error --title="GPG Signature Error" --text="Error creating the signature:\n\n${output}" 215 | exit 1 216 | fi 217 | 218 | -------------------------------------------------------------------------------- /thunar-gpg-info.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Informs about to whom the file has been encrypted for. 4 | # 5 | # * Put this file into your home binary dir: ~/bin/ 6 | # * Make it executable: chmod +x 7 | # 8 | # 9 | # Required Software: 10 | # ------------------------- 11 | # * gpg 12 | # * zenity 13 | # 14 | # 15 | # Thunar Integration 16 | # ------------------------ 17 | # 18 | # Command: ~/bin/thunar-gpg-info.sh -f %f 19 | # File Pattern: * 20 | # Appear On: Other Files 21 | # 22 | # 23 | # Usage: 24 | # ------------------------- 25 | # thunar-gpg-info.sh -f 26 | # 27 | # required: 28 | # -f input filename 29 | # 30 | # Note: 31 | # ------------------------- 32 | # 33 | # Feel free to adjust/improve and commit back to: 34 | # https://github.com/cytopia/thunar-custom-actions 35 | # 36 | 37 | 38 | usage() { 39 | echo "$0 -f " 40 | echo 41 | echo " required:" 42 | echo " -f input filename" 43 | echo 44 | } 45 | 46 | 47 | while getopts ":f:" i; do 48 | case "${i}" in 49 | f) 50 | f=${OPTARG} 51 | ;; 52 | *) 53 | echo "Error - unrecognized option $1" 1>&2; 54 | usage 55 | ;; 56 | esac 57 | done 58 | shift $((OPTIND-1)) 59 | 60 | # Check if file is specified 61 | if [ -z "${f}" ]; then 62 | echo "Error - no file specified" 1>&2; 63 | usage 64 | exit 1 65 | fi 66 | 67 | # Check if gpg exists 68 | if ! command -v gpg >/dev/null 2>&1 ; then 69 | echo "Error - 'gpg' not found." 1>&2 70 | exit 1 71 | fi 72 | 73 | # Check if zenity exists 74 | if ! command -v zenity >/dev/null 2>&1 ; then 75 | echo "Error - 'zenity' not found." 1>&2 76 | exit 1 77 | fi 78 | 79 | 80 | ################################################################################ 81 | # 82 | # GPG INFO FUNCTIONS 83 | # 84 | ################################################################################ 85 | validate () { 86 | _file="${1}" 87 | error="$(gpg --list-packets --list-only "${_file}" 2> /dev/null)" 88 | echo $? 89 | } 90 | getRecipientKey() { 91 | _file="${1}" 92 | 93 | gpg --list-packets --list-only "${_file}" 2>/dev/null | \ 94 | grep 'pubkey' | \ 95 | sed 's/.*keyid//g' | \ 96 | grep -oE '[A-Fa-f0-9]+' 97 | } 98 | getEncrypterKey() { 99 | _file="${1}" 100 | 101 | gpg --passphrase '' --list-packets --batch --yes "${_file}" 2>&1 | \ 102 | grep -oE '[[:space:]]+ID[[:space:]]+[A-Fa-f0-9]+' | \ 103 | sed 's/^[[:space:]]*ID[[:space:]]*//g' 104 | } 105 | ################################################################################ 106 | # 107 | # GET PUBLIC KEYS 108 | # 109 | ################################################################################ 110 | getNameByPubKey() { 111 | _key="${1}" 112 | if [ "${_key}" = "" ]; then 113 | echo "" 114 | return 115 | fi 116 | gpg --list-public-keys --keyid-format short "${_key}" 2>/dev/null | \ 117 | grep '^uid' | \ 118 | sed 's/^uid[[:space:]]*//g' | \ 119 | sed 's/\s*<.*@.*>$//g' 120 | } 121 | getMailByPubKey() { 122 | _key="${1}" 123 | if [ "${_key}" = "" ]; then 124 | echo "" 125 | return 126 | fi 127 | gpg --list-public-keys --keyid-format short "${_key}" 2>/dev/null | \ 128 | grep '^uid' | \ 129 | sed 's/^uid[[:space:]]*//g' | \ 130 | grep -oE '<.+@.+>' | \ 131 | sed 's///g' 133 | 134 | } 135 | getBitByPubKey() { 136 | _key="${1}" 137 | if [ "${_key}" = "" ]; then 138 | echo "" 139 | return 140 | fi 141 | gpg --list-public-keys --keyid-format short "${_key}" 2>/dev/null | \ 142 | grep '^pub' | \ 143 | sed 's/^pub[[:space:]]*//g' | \ 144 | grep -oE '[0-9]+./' | \ 145 | grep -oE '[0-9]+' 146 | } 147 | 148 | ################################################################################ 149 | # 150 | # SECRET KEY FUNCTIONS 151 | # 152 | ################################################################################ 153 | getNameBySecKey() { 154 | _key="${1}" 155 | if [ "${_key}" = "" ]; then 156 | echo "" 157 | return 158 | fi 159 | gpg --list-secret-keys --keyid-format short "${_key}" 2>/dev/null | \ 160 | grep '^uid' | \ 161 | sed 's/^uid[[:space:]]*//g' | \ 162 | sed 's/\s*<.*@.*>$//g' 163 | } 164 | getMailBySecKey() { 165 | _key="${1}" 166 | if [ "${_key}" = "" ]; then 167 | echo "" 168 | return 169 | fi 170 | gpg --list-secret-keys --keyid-format short "${_key}" 2>/dev/null | \ 171 | grep '^uid' | \ 172 | sed 's/^uid[[:space:]]*//g' | \ 173 | grep -oE '<.+@.+>' | \ 174 | sed 's///g' 176 | 177 | } 178 | getBitBySecKey() { 179 | _key="${1}" 180 | if [ "${_key}" = "" ]; then 181 | echo "" 182 | return 183 | fi 184 | gpg --list-secret-keys --keyid-format short "${_key}" 2>/dev/null | \ 185 | grep '^sec' | \ 186 | sed 's/^sec[[:space:]]*//g' | \ 187 | grep -oE '[0-9]+./' | \ 188 | grep -oE '[0-9]+' 189 | } 190 | 191 | 192 | 193 | 194 | error="$( validate "${f}" )" 195 | getEncrypterKey "${f}" 196 | if [ "$error" -eq "0" ]; then 197 | encrypterKey="$( getEncrypterKey "${f}" )" 198 | encrypterName="$( getNameBySecKey "${encrypterKey}" )" 199 | encrypterMail="$( getMailBySecKey "${encrypterKey}" )" 200 | 201 | recipientKey="$( getRecipientKey "${f}" )" 202 | recipientName="$( getNameByPubKey "${recipientKey}" )" 203 | recipientMail="$( getMailByPubKey "${recipientKey}" )" 204 | 205 | output="" 206 | output="${output}Encrypted by:\n" 207 | output="${output}--------------------------------------------------\n" 208 | output="${output}Name: ${encrypterName}\n" 209 | output="${output}Mail: ${encrypterMail}\n" 210 | output="${output}Key: ${encrypterKey}\n" 211 | output="${output}\n" 212 | output="${output}Encrypted for:\n" 213 | output="${output}--------------------------------------------------\n" 214 | output="${output}Name: ${recipientName}\n" 215 | output="${output}Mail: ${recipientMail}\n" 216 | output="${output}Key: ${recipientKey}\n" 217 | 218 | zenity --info --text="${output}" 219 | exit $? 220 | else 221 | zenity --info --text="No valid gpg data found" 222 | exit 1 223 | fi 224 | 225 | -------------------------------------------------------------------------------- /thunar-gpg-encrypt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # List available public recipient keys, encrypt the file/folder 4 | # for the specified recipient by his/her public key and sign it 5 | # with your own key. 6 | # 7 | # * Put this file into your home binary dir: ~/bin/ 8 | # * Make it executable: chmod +x 9 | # 10 | # 11 | # Required Software: 12 | # ------------------------- 13 | # * gpg 14 | # * zenity 15 | # * pinentry-gtk-2 or pinentry-mac 16 | # 17 | # 18 | # Thunar Integration 19 | # ------------------------ 20 | # 21 | # Command: ~/bin/thunar-gpg-encrypt.sh -f %f 22 | # File Pattern: * 23 | # Appear On: Select everything 24 | # 25 | # 26 | # Usage: 27 | # ------------------------- 28 | # thunar-gpg-encrypt.sh -f / 29 | # 30 | # required: 31 | # -f input filename/directory 32 | # 33 | # Note: 34 | # ------------------------- 35 | # 36 | # Feel free to adjust/improve and commit back to: 37 | # https://github.com/cytopia/thunar-custom-actions 38 | # 39 | 40 | 41 | ################################################################################ 42 | # 43 | # Functions 44 | # 45 | ################################################################################ 46 | 47 | 48 | # 49 | # Display usage 50 | # 51 | usage() { 52 | echo "$0 -f /" 53 | echo 54 | echo " required:" 55 | echo " -f input filename/folder" 56 | echo 57 | } 58 | 59 | ################################################################################ 60 | # 61 | # GET PUBLIC KEYS 62 | # 63 | ################################################################################ 64 | getAllPubKeysShort() { 65 | gpg --list-public-keys --keyid-format short 2>/dev/null | \ 66 | grep '^pub' | \ 67 | sed 's/^pub[[:space:]]*[0-9]*.\///g' | \ 68 | grep -oE '^[0-9A-Fa-f]+' 69 | } 70 | getNameByPubKey() { 71 | _key="${1}" 72 | if [ "${_key}" = "" ]; then 73 | echo "" 74 | return 75 | fi 76 | gpg --list-public-keys --keyid-format short "${_key}" 2>/dev/null | \ 77 | grep '^uid' | \ 78 | sed 's/^uid[[:space:]]*//g' | \ 79 | sed 's/\s*<.*@.*>$//g' 80 | } 81 | getMailByPubKey() { 82 | _key="${1}" 83 | if [ "${_key}" = "" ]; then 84 | echo "" 85 | return 86 | fi 87 | gpg --list-public-keys --keyid-format short "${_key}" 2>/dev/null | \ 88 | grep '^uid' | \ 89 | sed 's/^uid[[:space:]]*//g' | \ 90 | grep -oE '<.+@.+>' | \ 91 | sed 's///g' 93 | 94 | } 95 | getBitByPubKey() { 96 | _key="${1}" 97 | if [ "${_key}" = "" ]; then 98 | echo "" 99 | return 100 | fi 101 | gpg --list-public-keys --keyid-format short "${_key}" 2>/dev/null | \ 102 | grep '^pub' | \ 103 | sed 's/^pub[[:space:]]*//g' | \ 104 | grep -oE '[0-9]+./' | \ 105 | grep -oE '[0-9]+' 106 | } 107 | 108 | 109 | ################################################################################ 110 | # 111 | # GET PRIVATE KEYS 112 | # 113 | ################################################################################ 114 | getAllSecKeysShort() { 115 | gpg --list-secret-keys --keyid-format short 2>/dev/null | \ 116 | grep '^sec' | \ 117 | sed 's/^sec[[:space:]]*[0-9]*.\///g' | \ 118 | grep -oE '^[0-9A-Fa-f]+' 119 | } 120 | getNameBySecKey() { 121 | _key="${1}" 122 | if [ "${_key}" = "" ]; then 123 | echo "" 124 | return 125 | fi 126 | gpg --list-secret-keys --keyid-format short "${_key}" 2>/dev/null | \ 127 | grep '^uid' | \ 128 | sed 's/^uid[[:space:]]*//g' | \ 129 | sed 's/\s*<.*@.*>$//g' 130 | } 131 | getMailBySecKey() { 132 | _key="${1}" 133 | if [ "${_key}" = "" ]; then 134 | echo "" 135 | return 136 | fi 137 | gpg --list-secret-keys --keyid-format short "${_key}" 2>/dev/null | \ 138 | grep '^uid' | \ 139 | sed 's/^uid[[:space:]]*//g' | \ 140 | grep -oE '<.+@.+>' | \ 141 | sed 's///g' 143 | 144 | } 145 | getBitBySecKey() { 146 | _key="${1}" 147 | if [ "${_key}" = "" ]; then 148 | echo "" 149 | return 150 | fi 151 | gpg --list-secret-keys --keyid-format short "${_key}" 2>/dev/null | \ 152 | grep '^sec' | \ 153 | sed 's/^sec[[:space:]]*//g' | \ 154 | grep -oE '[0-9]+./' | \ 155 | grep -oE '[0-9]+' 156 | } 157 | 158 | 159 | 160 | 161 | 162 | 163 | ################################################################################ 164 | # 165 | # ZENITY FUNCTIONS 166 | # 167 | ################################################################################ 168 | 169 | 170 | # 171 | # Display zenity box for choosing the recipient 172 | # from a list of all public key. 173 | # 174 | # @output string Public key string (bits, key, name, email) 175 | # 176 | chooseRecipient () { 177 | output="" 178 | IFS=' 179 | ' 180 | for key in $( getAllPubKeysShort ); do 181 | name="$( getNameByPubKey "${key}" )" 182 | mail="$( getMailByPubKey "${key}" )" 183 | bit="$( getBitByPubKey "${key}" )" 184 | output="${output}\"${bit}\" \"${key}\" \"${name}\" \"${mail}\" " 185 | done 186 | 187 | CMD="zenity --list \ 188 | --width=550 --height=250 \ 189 | --title=\"GPG Encrypt File for...\" \ 190 | --print-column=2 \ 191 | --text=\"Choose Recipient\" \ 192 | --column=\"Bit\" --column=\"Key\" --column=\"Name\" --column=\"Email\" ${output}" 193 | 194 | eval "${CMD}" 195 | } 196 | 197 | 198 | # 199 | # Display zenity box for choosing your own private keys 200 | # from a list. 201 | # 202 | # @output string Private key string (bits, key, name, email) 203 | # 204 | chooseSecret () { 205 | output="" 206 | IFS=' 207 | ' 208 | for key in $( getAllSecKeysShort ); do 209 | name="$( getNameBySecKey "${key}" )" 210 | mail="$( getMailBySecKey "${key}" )" 211 | bit="$( getBitBySecKey "${key}" )" 212 | output="${output}\"${bit}\" \"${key}\" \"${name}\" \"${mail}\" " 213 | done 214 | 215 | CMD="zenity --list \ 216 | --width=550 --height=250 \ 217 | --title=\"Choose private key...\" \ 218 | --print-column=2 \ 219 | --text=\"Choose your private key\" \ 220 | --column=\"Bit\" --column=\"Key\" --column=\"Name\" --column=\"Email\" ${output}" 221 | 222 | eval "${CMD}" 223 | } 224 | 225 | 226 | # 227 | # Display secure dialog to read in the pasword 228 | # 229 | # @param string My chosen secret key 230 | # @output string My entered password 231 | readPassword () { 232 | _my_key="$1" 233 | _my_mail="$(getMailBySecKey "${_my_key}")" 234 | printf "SETDESC Enter your password for: %s (%s)\nGETPIN\n" "${_my_key}" "${_my_mail}" | ${BIN_PINENTRY} 2> /dev/null | grep "D" | awk '{print $2}' 235 | } 236 | 237 | 238 | 239 | ################################################################################ 240 | # 241 | # Evaluate command line arguments 242 | # 243 | ################################################################################ 244 | 245 | # Loop over cmd args 246 | while getopts ":f:" i; do 247 | case "${i}" in 248 | f) 249 | f=${OPTARG} 250 | ;; 251 | *) 252 | echo "Error - unrecognized option $1" 1>&2; 253 | usage 254 | ;; 255 | esac 256 | done 257 | shift $((OPTIND-1)) 258 | 259 | # Check if file is specified 260 | if [ -z "${f}" ]; then 261 | echo "Error - no file specified" 1>&2; 262 | usage 263 | exit 1 264 | fi 265 | 266 | 267 | ################################################################################ 268 | # 269 | # Check binary requirements 270 | # 271 | ################################################################################ 272 | 273 | 274 | # Check if gpg exists 275 | if ! command -v gpg >/dev/null 2>&1 ; then 276 | echo "Error - 'gpg' not found." 1>&2 277 | exit 1 278 | fi 279 | 280 | # Check if pinentry-gtk-2 exists 281 | BIN_PINENTRY="" 282 | if [ "$(uname)" != "Darwin" ]; then 283 | if ! command -v pinentry-gtk-2 >/dev/null 2>&1 ; then 284 | echo "Error - 'pinentry-gtk-2' not found." 1>&2 285 | exit 1 286 | fi 287 | BIN_PINENTRY="pinentry-gtk-2" 288 | else 289 | if ! command -v pinentry-mac >/dev/null 2>&1 ; then 290 | echo "Error - 'pinentry-mac' not found." 1>&2 291 | exit 1 292 | fi 293 | BIN_PINENTRY="pinentry-mac" 294 | fi 295 | 296 | # Check if zenity exists 297 | if ! command -v zenity >/dev/null 2>&1 ; then 298 | echo "Error - 'zenity' not found." 1>&2 299 | exit 1 300 | fi 301 | 302 | # Check if input is file or folder 303 | if [ ! -f "${f}" ] && [ ! -d "${f}" ]; then 304 | zenity --error --text="Input is neither a file, nor a folder." 305 | exit 1 306 | fi 307 | 308 | 309 | 310 | 311 | ################################################################################ 312 | # 313 | # Main entry point 314 | # 315 | ################################################################################ 316 | 317 | r="$(chooseRecipient)" 318 | if [ -z "${r}" ]; then 319 | zenity --error --text="No Recipient specified." 320 | exit 1 321 | fi 322 | # fix zenity bug on double click 323 | # https://bugzilla.gnome.org/show_bug.cgi?id=698683 324 | r="$(echo "${r}" | awk '{split($0,a,"|"); print a[1]}')" 325 | 326 | 327 | 328 | u="$(chooseSecret)" 329 | if [ -z "${u}" ]; then 330 | zenity --error --text="No Secret key specified." 331 | exit 1 332 | fi 333 | # fix zenity bug on double click 334 | # https://bugzilla.gnome.org/show_bug.cgi?id=698683 335 | u="$(echo "${u}" | awk '{split($0,a,"|"); print a[1]}')" 336 | 337 | p="$(readPassword "${u}")" 338 | if [ -z "${p}" ]; then 339 | zenity --error --text="No Password specified." 340 | exit 1 341 | fi 342 | 343 | 344 | # Encrypt folder 345 | if [ -d "${f}" ]; then 346 | parentdir="$(dirname "${f}")" 347 | directory="$(basename "${f}")" 348 | 349 | error="$(tar c -C "${parentdir}" "${directory}" | gpg -e -s --yes --batch --local-user "${u}" --recipient "${r}" --passphrase "${p}" -o "${parentdir}/${directory}.tar.gpg" 2>&1)" 350 | errno=$? 351 | else 352 | error="$(gpg -e -s --yes --batch --local-user "${u}" --recipient "${r}" --passphrase "${p}" "${f}" 2>&1)" 353 | errno=$? 354 | fi 355 | 356 | if [ "$errno" -gt "0" ]; then 357 | zenity --error --text="${error}\nreturn code: ${errno}" 358 | exit 1 359 | else 360 | zenity --info --text="Encrypted." 361 | exit $? 362 | fi 363 | 364 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Thunar Custom Actions 2 | 3 | [![Build Status](https://travis-ci.org/cytopia/thunar-custom-actions.svg?branch=master)](https://travis-ci.org/cytopia/thunar-custom-actions) 4 | 5 | The following actions can also be used in nautilus or any other file manager that supports custom actions. 6 | I personally prefer thunar because of speed. 7 | 8 | 9 | If any of the actions don't work anymore (especially the upload ones), please report here, so I can fix it. 10 | 11 | --- 12 | 13 | **Latest added action**: 14 | 15 | * `thunar-gpg-sign.sh` 16 | * `thunar-gpg-verify-signature.sh` 17 | * `thunar-video-to-gif.sh` 18 | 19 | 20 | --- 21 | 22 | ## Actions 23 | 24 | ### Multimedia 25 | 26 | #### ![Thunar Convert to PNG](/icons/thunar-convert-to-png.png) [thunar-convert-to-png.sh](thunar-convert-to-png.sh) 27 | [![Type](https://img.shields.io/badge/type-%2Fbin%2Fsh-red.svg)](https://en.wikipedia.org/?title=Bourne_shell) ![GUI](https://img.shields.io/badge/GUI-no%20output-blue.svg) 28 | This action converts any image file to a png image. (Should also work with layered PSD files). 29 | **Requirements:** `convert` 30 | **Thunar settings:** 31 | 32 | | name | value | 33 | |--------------|--------------------------------| 34 | | Name | Convert to png | 35 | | Command | thunar-convert-to-png.sh -f %f | 36 | | File pattern | * | 37 | | Appear on | Image files | 38 | 39 | #### ![Thunar Convert to JPG](/icons/thunar-convert-to-jpg.png) [thunar-convert-to-jpg.sh](thunar-convert-to-jpg.sh) 40 | [![Type](https://img.shields.io/badge/type-%2Fbin%2Fsh-red.svg)](https://en.wikipedia.org/?title=Bourne_shell) ![GUI](https://img.shields.io/badge/GUI-no%20output-blue.svg) 41 | This action converts any image file to a jpg image. (Should also work with layered PSD files). 42 | **Requirements:** `convert` 43 | **Thunar settings:** 44 | 45 | | name | value | 46 | |--------------|--------------------------------| 47 | | Name | Convert to jpg | 48 | | Command | thunar-convert-to-jpg.sh -f %f | 49 | | File pattern | * | 50 | | Appear on | Image files | 51 | 52 | #### ![Thunar Media Info](/icons/thunar-media-info.png) [thunar-media-info.sh](thunar-media-info.sh) 53 | [![Type](https://img.shields.io/badge/type-%2Fbin%2Fsh-red.svg)](https://en.wikipedia.org/?title=Bourne_shell) [![GUI](https://img.shields.io/badge/GUI-zenity-blue.svg)](https://help.gnome.org/users/zenity/stable/) 54 | This action pops up a zenity-based window and displays encoding information for an audio or video file. 55 | **Requirements:** `zenity` and `ffmpeg` 56 | **Thunar settings:** 57 | 58 | | name | value | 59 | |--------------|--------------------------------| 60 | | Name | Media info | 61 | | Command | thunar-media-info.sh -f %f -t %n | 62 | | File pattern | * | 63 | | Appear on | Audio files, Video files | 64 | 65 | 66 | #### ![Thunar Convert Video to Gif](/icons/thunar-media-info.png) [thunar-video-to-gif.sh](thunar-video-to-gif.sh) 67 | [![Type](https://img.shields.io/badge/type-%2Fbin%2Fsh-red.svg)](https://en.wikipedia.org/?title=Bourne_shell) [![GUI](https://img.shields.io/badge/GUI-zenity-blue.svg)](https://help.gnome.org/users/zenity/stable/) 68 | This action pops up a zenity-based window (or via `read` on the shell) asking for the final video width and creates a high quality gif from your input video. 69 | 70 | **High quality gif:** This is achieved by doing a two-way-run. The first run creates the color palette from the video and the second run creates the gif based on that palette. 71 | 72 | **Requirements:** `ffmpeg` 73 | **Optional:** `zenity` for gui output 74 | **Note:** Works for cli-only (`-c`) or via `zenity`-gui 75 | **Thunar settings:** 76 | 77 | | name | value | 78 | |--------------|--------------------------------| 79 | | Name | Video to Gif | 80 | | Command | thunar-video-to-gif.sh -f %f | 81 | | File pattern | * | 82 | | Appear on | Video files | 83 | 84 | 85 | 86 | --- 87 | 88 | ### Security 89 | 90 | #### ![Thunar Openssl Encrypt/Decrypt](/icons/thunar-gpg-encrypt.png) [thunar-openssl-encrypt-decrypt.sh](thunar-openssl-encrypt-decrypt.sh) 91 | [![Type](https://img.shields.io/badge/type-bash-red.svg)](https://en.wikipedia.org/?title=Bourne_shell) [![GUI](https://img.shields.io/badge/GUI-zenity-blue.svg)](https://help.gnome.org/users/zenity/stable/) 92 | This action will encrypt/decrypt a file based on openssl's symmetric encryption. 93 | **Requirements:** `openssl` and `zenity` 94 | **Thunar settings:** 95 | 96 | | name | value | 97 | |--------------|--------------------------------| 98 | | Name | Openssl Encrypt/Decrypt | 99 | | Command | thunar-openssl-encrypt-decrypt.sh -f %f | 100 | | File pattern | * | 101 | | Appear on | Everything | 102 | 103 | For detailed explanation and screenshots see this blog entry: [alan-mushi.github.io](https://alan-mushi.github.io/asap/2016/02/09/usable-openssl-symmetric-encryption.html) 104 | 105 | 106 | #### ![Thunar GPG Encrypt](/icons/thunar-gpg-encrypt.png) [thunar-gpg-encrypt.sh](thunar-gpg-encrypt.sh) 107 | [![Type](https://img.shields.io/badge/type-%2Fbin%2Fsh-red.svg)](https://en.wikipedia.org/?title=Bourne_shell) [![GUI](https://img.shields.io/badge/GUI-zenity-blue.svg)](https://help.gnome.org/users/zenity/stable/) 108 | This action pops up a zenity-based window letting you choose from your gpg recipients and encrypts and signs the file with your chosen gpg key. (Asymmetric encryption). 109 | **Requirements:** `gpg`, `zenity` and `pinentry-gtk-2` 110 | **Thunar settings:** 111 | 112 | | name | value | 113 | |--------------|--------------------------------| 114 | | Name | GPG Encrypt | 115 | | Command | thunar-gpg-encrypt.sh -f %f | 116 | | File pattern | * | 117 | | Appear on | Everything | 118 | 119 | 120 | #### ![Thunar GPG Decrypt](/icons/thunar-gpg-decrypt.png) [thunar-gpg-decrypt.sh](thunar-gpg-decrypt.sh) 121 | [![Type](https://img.shields.io/badge/type-%2Fbin%2Fsh-red.svg)](https://en.wikipedia.org/?title=Bourne_shell) ![GUI](https://img.shields.io/badge/GUI-terminal-blue.svg) 122 | This action pops up a terminal window for password entry and decrypts the file with your private gpg key. (Asymmetric encryption). 123 | **Requirements:** `gpg` 124 | **Todo:** Make gui-based password entry form. 125 | **Thunar settings:** 126 | 127 | | name | value | 128 | |--------------|--------------------------------| 129 | | Name | GPG Decrypt | 130 | | Command | urxvtcd -e thunar-gpg-decrypt.sh -f %f | 131 | | File pattern | * | 132 | | Appear on | Other files | 133 | 134 | 135 | #### ![Thunar Sign](/icons/thunar-gpg-info.png) [thunar-gpg-sign.sh](thunar-gpg-sign.sh) 136 | [![Type](https://img.shields.io/badge/type-%2Fbin%2Fsh-red.svg)](https://en.wikipedia.org/?title=Bourne_shell) [![GUI](https://img.shields.io/badge/GUI-zenity-blue.svg)](https://help.gnome.org/users/zenity/stable/) 137 | This action pops up a zenity-based window, let's you choose from a list of your secret keys and creates an ascii-armored separate signature file. 138 | **Requirements:** `gpg` and `zenity` 139 | **Thunar settings:** 140 | 141 | | name | value | 142 | |--------------|--------------------------------| 143 | | Name | GPG Sign | 144 | | Command | thunar-gpg-sign.sh -f %f | 145 | | File pattern | * | 146 | | Appear on | Other files | 147 | 148 | 149 | 150 | #### ![Thunar GPG Info](/icons/thunar-gpg-info.png) [thunar-gpg-info.sh](thunar-gpg-info.sh) 151 | [![Type](https://img.shields.io/badge/type-%2Fbin%2Fsh-red.svg)](https://en.wikipedia.org/?title=Bourne_shell) [![GUI](https://img.shields.io/badge/GUI-zenity-blue.svg)](https://help.gnome.org/users/zenity/stable/) 152 | This action pops up a zenity-based window and displays information about the encryption of the current file. (Asymmetric encryption). 153 | **Requirements:** `gpg` and `zenity` 154 | **Thunar settings:** 155 | 156 | | name | value | 157 | |--------------|--------------------------------| 158 | | Name | GPG Info | 159 | | Command | thunar-gpg-info.sh -f %f | 160 | | File pattern | * | 161 | | Appear on | Other files | 162 | 163 | 164 | #### ![Thunar GPG Verify Signature](/icons/thunar-gpg-info.png) [thunar-gpg-verify-signature.sh](thunar-gpg-verify-signature.sh) 165 | [![Type](https://img.shields.io/badge/type-%2Fbin%2Fsh-red.svg)](https://en.wikipedia.org/?title=Bourne_shell) [![GUI](https://img.shields.io/badge/GUI-zenity-blue.svg)](https://help.gnome.org/users/zenity/stable/) 166 | This action pops up a zenity-based window and displays verification information about the gpg signature. 167 | **Requirements:** `gpg` and `zenity` 168 | **Thunar settings:** 169 | 170 | | name | value | 171 | |--------------|--------------------------------| 172 | | Name | GPG Verify Signature | 173 | | Command | thunar-gpg-verify-signature.sh.sh -f %f | 174 | | File pattern | * | 175 | | Appear on | Other files | 176 | 177 | 178 | --- 179 | 180 | ### Uploads 181 | 182 | #### ![Thunar Paste to Gist](/icons/thunar-paste-to-gist.png) [thunar-paste-to-gist.sh](thunar-paste-to-gist.sh) 183 | [![Type](https://img.shields.io/badge/type-%2Fbin%2Fsh-red.svg)](https://en.wikipedia.org/?title=Bourne_shell) [![GUI](https://img.shields.io/badge/GUI-zenity-blue.svg)](https://help.gnome.org/users/zenity/stable/) 184 | This action pastes a text file to gist (in private mode) and pops up a zenity-based window displaying the paste url (shortened). Additionally the paste url will also be copied to clipboard. 185 | **Requirements:** `zenity` and `gist` 186 | **Thunar settings:** 187 | 188 | | name | value | 189 | |--------------|--------------------------------| 190 | | Name | Paste to gist | 191 | | Command | thunar-paste-to-gist.sh -f %f | 192 | | File pattern | * | 193 | | Appear on | Text files | 194 | 195 | 196 | #### ![Thunar Paste to Pastebin](/icons/thunar-paste-to-pastebin.png) [thunar-paste-to-pastebin.sh](thunar-paste-to-pastebin.sh) 197 | [![Type](https://img.shields.io/badge/type-%2Fbin%2Fsh-red.svg)](https://en.wikipedia.org/?title=Bourne_shell) [![GUI](https://img.shields.io/badge/GUI-zenity-blue.svg)](https://help.gnome.org/users/zenity/stable/) 198 | This action pastes a text file to pastebin and pops up a zenity-based window displaying the paste url. 199 | **Requirements:** `zenity` and `curl` 200 | **Note:** The pastebin API only allows 25 pastes per free account per every 24 hours. I have added two API keys inside the source. If however you plan on using this thunar action, make sure to get your own API key and replace it. The second thought I had is not to use the API directly, but try to use the normal upload form via curl so that no API key is required at all. 201 | **Todo:** Expand file type recognition to set the proper syntax highlighting scheme for var `PB_API_FORMAT`. 202 | **Thunar settings:** 203 | 204 | | name | value | 205 | |--------------|--------------------------------| 206 | | Name | Paste to pastebin | 207 | | Command | thunar-paste-to-pastebin.sh -f %f | 208 | | File pattern | * | 209 | | Appear on | Text files | 210 | 211 | #### ![Thunar Upload to Imgur](/icons/thunar-upload-to-imgur.png) [thunar-upload-to-imgur.sh](thunar-upload-to-imgur.sh) 212 | [![Type](https://img.shields.io/badge/type-bash-red.svg)](https://en.wikipedia.org/wiki/Bash) [![GUI](https://img.shields.io/badge/GUI-zenity-blue.svg)](https://help.gnome.org/users/zenity/stable/) 213 | This action uploads an image file to imgur and pops up a zenity-based window displaying the upload url. 214 | **Requirements:** `zenity`, `gawk`, `curl` 215 | **Note:** Upload key is included :-) 216 | **Todo:** Evaluate if it is possible to get rid of `gawk` requirement. 217 | **Thunar settings:** 218 | 219 | | name | value | 220 | |--------------|--------------------------------| 221 | | Name | Upload to imgur | 222 | | Command | thunar-upload-to-imgur.sh -f %f | 223 | | File pattern | * | 224 | | Appear on | Image files | 225 | 226 | 227 | 228 | 229 | #### ![Thunar Upload to Postimage](/icons/thunar-upload-to-postimage.png) [thunar-upload-to-postimage.sh](thunar-upload-to-postimage.sh) 230 | [![Type](https://img.shields.io/badge/type-bash-red.svg)](https://en.wikipedia.org/wiki/Bash) [![GUI](https://img.shields.io/badge/GUI-zenity-blue.svg)](https://help.gnome.org/users/zenity/stable/) 231 | This action uploads an image file to postimage.org and pops up a zenity-based window displaying the upload url. 232 | **Requirements:** `zenity`, `gawk`, `curl` 233 | **Todo:** Evaluate if it is possible to get rid of `gawk` requirement. 234 | **Thunar settings:** 235 | 236 | | name | value | 237 | |--------------|--------------------------------| 238 | | Name | Upload to postimage | 239 | | Command | thunar-upload-to-postimage.sh -f %f | 240 | | File pattern | * | 241 | | Appear on | Image files | 242 | 243 | 244 | ## General Setup 245 | 246 | All actions require the `-f` parameter which specifies the file to work on. Prior Thunar/Nautilus integration you can test them all on the command line to make sure they do what they are supposed to do: 247 | ```bash 248 | thunar-action.sh -f /path/to/file 249 | ``` 250 | The equivilent thunar command would be: 251 | ```bash 252 | /path/to/thunar-action.sh -f %f 253 | ``` 254 | 255 | **Note about substitutions in Thunar**: 256 | ```bash 257 | %f The path to the first selected file 258 | %F The paths to all selected files 259 | %d Directory containing the file that is passed in %f 260 | %D Directory containing the files that are passed in %F 261 | %n The first selected filename (without path) 262 | %N The selected filenames (without paths) 263 | ``` 264 | 265 | 266 | ## TODO / Ideas 267 | 268 | * Image: convert from ... to anything via list (dropdown or radio) of target formats (jpg, png, gif, etc). Possibly also some convert options via slider or checkboxes. 269 | * Video: encode/re-encode videos to target format (dropdown or radio for target formats). Also some ffmpeg quality options via slider, textfields and/or checkboxes 270 | * Video to gif 271 | 272 | 273 | 274 | ## Contributions 275 | 276 | Thanks to the following for contributing: 277 | 278 | * [matiasw](https://github.com/matiasw) 279 | * [alan-mushi](https://github.com/alan-mushi) 280 | 281 | 282 | ## License 283 | 284 | [![license](https://poser.pugx.org/cytopia/mysqldump-secure/license)](http://opensource.org/licenses/mit) 285 | 286 | --------------------------------------------------------------------------------