"Fossies" - the Fresh Open Source Software Archive

Member "nnn-4.4/plugins/nuke" (23 Nov 2021, 18614 Bytes) of package /linux/misc/nnn-v4.4.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Bash source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "nuke": v4.3_vs_v4.4.

    1 #!/usr/bin/env sh
    2 
    3 # Description: Sample script to play files in apps by file type or mime
    4 #
    5 # Shell: POSIX compliant
    6 # Usage: nuke filepath
    7 #
    8 # Integration with nnn:
    9 #   1. Export the required config:
   10 #         export NNN_OPENER=/absolute/path/to/nuke
   11 #         # Otherwise, if nuke is in $PATH
   12 #         # export NNN_OPENER=nuke
   13 #   2. Run nnn with the program option to indicate a CLI opener
   14 #         nnn -c
   15 #         # The -c program option overrides option -e
   16 #   3. nuke can use nnn plugins (e.g. mocq is used for audio), $PATH is updated.
   17 #
   18 # Details:
   19 #   Inspired by ranger's scope.sh, modified for usage with nnn.
   20 #
   21 #   Guards against accidentally opening mime types like executables, shared libs etc.
   22 #
   23 #   Tries to play 'file' (1st argument) in the following order:
   24 #     1. by extension
   25 #     2. by mime (image, video, audio, pdf)
   26 #     3. by mime (other file types)
   27 #     4. by mime (prompt and run executables)
   28 #
   29 # Modification tips:
   30 #   1. Invokes CLI utilities by default. Set GUI to 1 to enable GUI apps.
   31 #   2. PAGER is "less -R".
   32 #   3. Start GUI apps in bg to unblock. Redirect stdout and strerr if required.
   33 #   4. Some CLI utilities are piped to the $PAGER, to wait and quit uniformly.
   34 #   5. If the output cannot be paged use "read -r _" to wait for user input.
   35 #   6. On a DE, try 'xdg-open' or 'open' in handle_fallback() as last resort.
   36 #
   37 #   Feel free to change the utilities to your favourites and add more mimes.
   38 #
   39 # Defaults:
   40 #   By extension (only the enabled ones):
   41 #      most archives: list with atool, bsdtar
   42 #      rar: list with unrar
   43 #      7-zip: list with 7z
   44 #      pdf: zathura (GUI), pdftotext, mutool, exiftool
   45 #      audio: mocq (nnn plugin using MOC), mpv, media_client (Haiku), mediainfo, exiftool
   46 #      avi|mkv|mp4: smplayer, mpv (GUI), ffmpegthumbnailer, mediainfo, exiftool
   47 #      log: vi
   48 #      torrent: rtorrent, transmission-show
   49 #      odt|ods|odp|sxw: odt2txt
   50 #      md: glow (https://github.com/charmbracelet/glow), lowdown (https://kristaps.bsd.lv/lowdown)
   51 #      htm|html|xhtml: w3m, lynx, elinks
   52 #      json: jq, python (json.tool module)
   53 #   Multimedia by mime:
   54 #      image/*: imv/sxiv/nsxiv (GUI), viu (https://github.com/atanunq/viu), img2txt, exiftool
   55 #      video/*: smplayer, mpv (GUI), ffmpegthumbnailer, mediainfo, exiftool
   56 #      audio/*: mocq (nnn plugin using MOC), mpv, media_client (Haiku), mediainfo, exiftool
   57 #      application/pdf: zathura (GUI), pdftotext, mutool, exiftool
   58 #   Other mimes:
   59 #      text/troff: man -l
   60 #      text/* | */xml: vi
   61 #      image/vnd.djvu): djvutxt, exiftool
   62 #
   63 # TODO:
   64 #   1. Adapt, test and enable all mimes
   65 #   2. Clean-up the unnecessary exit codes
   66 
   67 # set to 1 to enable GUI apps and/or BIN execution
   68 GUI="${GUI:-0}"
   69 BIN="${BIN:-0}"
   70 
   71 set -euf -o noclobber -o noglob -o nounset
   72 IFS="$(printf '%b_' '\n')"; IFS="${IFS%_}" # protect trailing \n
   73 
   74 PATH=$PATH:"${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins"
   75 IMAGE_CACHE_PATH="$(dirname "$1")"/.thumbs
   76 
   77 FPATH="$1"
   78 FNAME=$(basename "$1")
   79 EDITOR="${VISUAL:-${EDITOR:-vi}}"
   80 PAGER="${PAGER:-less -R}"
   81 ext="${FNAME##*.}"
   82 if [ -n "$ext" ]; then
   83     ext="$(printf "%s" "${ext}" | tr '[:upper:]' '[:lower:]')"
   84 fi
   85 
   86 is_mac() {
   87     uname | grep -q "Darwin"
   88 }
   89 
   90 handle_pdf() {
   91     if [ "$GUI" -ne 0 ]; then
   92         if is_mac; then
   93             nohup open "${FPATH}" >/dev/null 2>&1 &
   94         elif type zathura >/dev/null 2>&1; then
   95             nohup zathura "${FPATH}" >/dev/null 2>&1 &
   96         else
   97             return
   98         fi
   99     elif type pdftotext >/dev/null 2>&1; then
  100         ## Preview as text conversion
  101         pdftotext -l 10 -nopgbrk -q -- "${FPATH}" - | eval "$PAGER"
  102     elif type mutool >/dev/null 2>&1; then
  103         mutool draw -F txt -i -- "${FPATH}" 1-10 | eval "$PAGER"
  104     elif type exiftool >/dev/null 2>&1; then
  105         exiftool "${FPATH}" | eval "$PAGER"
  106     else
  107         return
  108     fi
  109     exit 0
  110 }
  111 
  112 handle_audio() {
  113     if type mocp >/dev/null 2>&1 && type mocq >/dev/null 2>&1; then
  114         mocq "${FPATH}" "opener" >/dev/null 2>&1
  115     elif type mpv >/dev/null 2>&1; then
  116         mpv "${FPATH}" >/dev/null 2>&1 &
  117     elif type media_client >/dev/null 2>&1; then
  118         media_client play "${FPATH}" >/dev/null 2>&1 &
  119     elif type mediainfo >/dev/null 2>&1; then
  120         mediainfo "${FPATH}" | eval "$PAGER"
  121     elif type exiftool >/dev/null 2>&1; then
  122         exiftool "${FPATH}"| eval "$PAGER"
  123     else
  124         return
  125     fi
  126     exit 0
  127 }
  128 
  129 handle_video() {
  130     if [ "$GUI" -ne 0 ]; then
  131         if is_mac; then
  132             nohup open "${FPATH}" >/dev/null 2>&1 &
  133         elif type smplayer >/dev/null 2>&1; then
  134             nohup smplayer "${FPATH}" >/dev/null 2>&1 &
  135         elif type mpv >/dev/null 2>&1; then
  136             nohup mpv "${FPATH}" >/dev/null 2>&1 &
  137         else
  138             return
  139         fi
  140     elif type ffmpegthumbnailer >/dev/null 2>&1; then
  141         # Thumbnail
  142         [ -d "${IMAGE_CACHE_PATH}" ] || mkdir "${IMAGE_CACHE_PATH}"
  143         ffmpegthumbnailer -i "${FPATH}" -o "${IMAGE_CACHE_PATH}/${FNAME}.jpg" -s 0
  144         viu -n "${IMAGE_CACHE_PATH}/${FNAME}.jpg" | eval "$PAGER"
  145     elif type mediainfo >/dev/null 2>&1; then
  146         mediainfo "${FPATH}" | eval "$PAGER"
  147     elif type exiftool >/dev/null 2>&1; then
  148         exiftool "${FPATH}"| eval "$PAGER"
  149     else
  150         return
  151     fi
  152     exit 0
  153 }
  154 
  155 # handle this extension and exit
  156 handle_extension() {
  157     case "${ext}" in
  158         ## Archive
  159         a|ace|alz|arc|arj|bz|bz2|cab|cpio|deb|gz|jar|lha|lz|lzh|lzma|lzo|\
  160         rpm|rz|t7z|tar|tbz|tbz2|tgz|tlz|txz|tZ|tzo|war|xpi|xz|Z|zip)
  161             if type atool >/dev/null 2>&1; then
  162                 atool --list -- "${FPATH}" | eval "$PAGER"
  163                 exit 0
  164             elif type bsdtar >/dev/null 2>&1; then
  165                 bsdtar --list --file "${FPATH}" | eval "$PAGER"
  166                 exit 0
  167             fi
  168             exit 1;;
  169         rar)
  170             if type unrar >/dev/null 2>&1; then
  171                 ## Avoid password prompt by providing empty password
  172                 unrar lt -p- -- "${FPATH}" | eval "$PAGER"
  173             fi
  174             exit 1;;
  175         7z)
  176             if type 7z >/dev/null 2>&1; then
  177                 ## Avoid password prompt by providing empty password
  178                 7z l -p -- "${FPATH}" | eval "$PAGER"
  179                 exit 0
  180             fi
  181             exit 1;;
  182 
  183         ## PDF
  184         pdf)
  185             handle_pdf
  186             exit 1;;
  187 
  188         ## Audio
  189         aac|flac|m4a|mid|midi|mpa|mp2|mp3|ogg|wav|wma)
  190             handle_audio
  191             exit 1;;
  192 
  193         ## Video
  194         avi|mkv|mp4)
  195             handle_video
  196             exit 1;;
  197 
  198         ## Log files
  199         log)
  200             "$EDITOR" "${FPATH}"
  201             exit 0;;
  202 
  203         ## BitTorrent
  204         torrent)
  205             if type rtorrent >/dev/null 2>&1; then
  206                 rtorrent "${FPATH}"
  207                 exit 0
  208             elif type transmission-show >/dev/null 2>&1; then
  209                 transmission-show -- "${FPATH}"
  210                 exit 0
  211             fi
  212             exit 1;;
  213 
  214         ## OpenDocument
  215         odt|ods|odp|sxw)
  216             if type odt2txt >/dev/null 2>&1; then
  217                 ## Preview as text conversion
  218                 odt2txt "${FPATH}" | eval "$PAGER"
  219                 exit 0
  220             fi
  221             exit 1;;
  222 
  223         ## Markdown
  224         md)
  225             if type glow >/dev/null 2>&1; then
  226                 glow -sdark "${FPATH}" | eval "$PAGER"
  227                 exit 0
  228             elif type lowdown >/dev/null 2>&1; then
  229                 lowdown -Tterm "${FPATH}" | eval "$PAGER"
  230                 exit 0
  231             fi
  232             ;;
  233 
  234         ## HTML
  235         htm|html|xhtml)
  236             ## Preview as text conversion
  237             if type w3m >/dev/null 2>&1; then
  238                 w3m -dump "${FPATH}" | eval "$PAGER"
  239                 exit 0
  240             elif type lynx >/dev/null 2>&1; then
  241                 lynx -dump -- "${FPATH}" | eval "$PAGER"
  242                 exit 0
  243             elif type elinks >/dev/null 2>&1; then
  244                 elinks -dump "${FPATH}" | eval "$PAGER"
  245                 exit 0
  246             fi
  247             ;;
  248 
  249         ## JSON
  250         json)
  251             if type jq >/dev/null 2>&1; then
  252                 jq --color-output . "${FPATH}" | eval "$PAGER"
  253                 exit 0
  254             elif type python >/dev/null 2>&1; then
  255                 python -m json.tool -- "${FPATH}" | eval "$PAGER"
  256                 exit 0
  257             fi
  258             ;;
  259     esac
  260 }
  261 
  262 # sets the variable abs_target, this should be faster than calling printf
  263 abspath() {
  264     case "$1" in
  265         /*) abs_target="$1";;
  266         *)  abs_target="$PWD/$1";;
  267     esac
  268 }
  269 
  270 # storing the result to a tmp file is faster than calling listimages twice
  271 listimages() {
  272     find -L "///${1%/*}" -maxdepth 1 -type f -print0 |
  273         grep -izZE '\.(jpe?g|png|gif|webp|tiff|bmp|ico|svg)$' |
  274         sort -z | tee "$tmp"
  275 }
  276 
  277 load_dir() {
  278     abspath "$2"
  279     tmp="${TMPDIR:-/tmp}/nuke_$$"
  280     trap 'rm -f $tmp' EXIT
  281     count="$(listimages "$abs_target" | grep -a -m 1 -ZznF "$abs_target" | cut -d: -f1)"
  282 
  283     if [ -n "$count" ]; then
  284         if [ "$GUI" -ne 0 ]; then
  285             xargs -0 nohup "$1" -n "$count" -- < "$tmp"
  286         else
  287             xargs -0 "$1" -n "$count" -- < "$tmp"
  288         fi
  289     else
  290         shift
  291         "$1" -- "$@" # fallback
  292     fi
  293 }
  294 
  295 handle_multimedia() {
  296     ## Size of the preview if there are multiple options or it has to be
  297     ## rendered from vector graphics. If the conversion program allows
  298     ## specifying only one dimension while keeping the aspect ratio, the width
  299     ## will be used.
  300     # local DEFAULT_SIZE="1920x1080"
  301 
  302     mimetype="${1}"
  303     case "${mimetype}" in
  304         ## SVG
  305         # image/svg+xml|image/svg)
  306         #     convert -- "${FPATH}" "${IMAGE_CACHE_PATH}" && exit 6
  307         #     exit 1;;
  308 
  309         ## DjVu
  310         # image/vnd.djvu)
  311         #     ddjvu -format=tiff -quality=90 -page=1 -size="${DEFAULT_SIZE}" \
  312         #           - "${IMAGE_CACHE_PATH}" < "${FPATH}" \
  313         #           && exit 6 || exit 1;;
  314 
  315         ## Image
  316         image/*)
  317             if [ "$GUI" -ne 0 ]; then
  318                 if is_mac; then
  319                     nohup open "${FPATH}" >/dev/null 2>&1 &
  320                     exit 0
  321                 elif type imvr >/dev/null 2>&1; then
  322                     load_dir imvr "${FPATH}" >/dev/null 2>&1 &
  323                     exit 0
  324                 elif type sxiv >/dev/null 2>&1; then
  325                     load_dir sxiv "${FPATH}" >/dev/null 2>&1 &
  326                     exit 0
  327                 elif type nsxiv >/dev/null 2>&1; then
  328                     load_dir nsxiv "${FPATH}" >/dev/null 2>&1 &
  329                     exit 0
  330                 fi
  331             elif type viu >/dev/null 2>&1; then
  332                 viu -n "${FPATH}" | eval "$PAGER"
  333                 exit 0
  334             elif type img2txt >/dev/null 2>&1; then
  335                 img2txt --gamma=0.6 -- "${FPATH}" | eval "$PAGER"
  336                 exit 0
  337             elif type exiftool >/dev/null 2>&1; then
  338                 exiftool "${FPATH}" | eval "$PAGER"
  339                 exit 0
  340             fi
  341             # local orientation
  342             # orientation="$( identify -format '%[EXIF:Orientation]\n' -- "${FPATH}" )"
  343             ## If orientation data is present and the image actually
  344             ## needs rotating ("1" means no rotation)...
  345             # if [[ -n "$orientation" && "$orientation" != 1 ]]; then
  346                 ## ...auto-rotate the image according to the EXIF data.
  347                 # convert -- "${FPATH}" -auto-orient "${IMAGE_CACHE_PATH}" && exit 6
  348             # fi
  349 
  350             ## `w3mimgdisplay` will be called for all images (unless overridden
  351             ## as above), but might fail for unsupported types.
  352             exit 7;;
  353 
  354         ## PDF
  355         application/pdf)
  356             handle_pdf
  357             exit 1;;
  358 
  359         ## Audio
  360         audio/*)
  361             handle_audio
  362             exit 1;;
  363 
  364         ## Video
  365         video/*)
  366             handle_video
  367             exit 1;;
  368 
  369         #     pdftoppm -f 1 -l 1 \
  370         #              -scale-to-x "${DEFAULT_SIZE%x*}" \
  371         #              -scale-to-y -1 \
  372         #              -singlefile \
  373         #              -jpeg -tiffcompression jpeg \
  374         #              -- "${FPATH}" "${IMAGE_CACHE_PATH%.*}" \
  375         #         && exit 6 || exit 1;;
  376 
  377 
  378         ## ePub, MOBI, FB2 (using Calibre)
  379         # application/epub+zip|application/x-mobipocket-ebook|\
  380         # application/x-fictionbook+xml)
  381         #     # ePub (using https://github.com/marianosimone/epub-thumbnailer)
  382         #     epub-thumbnailer "${FPATH}" "${IMAGE_CACHE_PATH}" \
  383         #         "${DEFAULT_SIZE%x*}" && exit 6
  384         #     ebook-meta --get-cover="${IMAGE_CACHE_PATH}" -- "${FPATH}" \
  385         #         >/dev/null && exit 6
  386         #     exit 1;;
  387 
  388         ## Font
  389         # application/font*|application/*opentype)
  390         #     preview_png="/tmp/$(basename "${IMAGE_CACHE_PATH%.*}").png"
  391         #     if fontimage -o "${preview_png}" \
  392         #                  --pixelsize "120" \
  393         #                  --fontname \
  394         #                  --pixelsize "80" \
  395         #                  --text "  ABCDEFGHIJKLMNOPQRSTUVWXYZ  " \
  396         #                  --text "  abcdefghijklmnopqrstuvwxyz  " \
  397         #                  --text "  0123456789.:,;(*!?') ff fl fi ffi ffl  " \
  398         #                  --text "  The quick brown fox jumps over the lazy dog.  " \
  399         #                  "${FPATH}";
  400         #     then
  401         #         convert -- "${preview_png}" "${IMAGE_CACHE_PATH}" \
  402         #             && rm "${preview_png}" \
  403         #             && exit 6
  404         #     else
  405         #         exit 1
  406         #     fi
  407         #     ;;
  408 
  409         ## Preview archives using the first image inside.
  410         ## (Very useful for comic book collections for example.)
  411         # application/zip|application/x-rar|application/x-7z-compressed|\
  412         #     application/x-xz|application/x-bzip2|application/x-gzip|application/x-tar)
  413         #     local fn=""; local fe=""
  414         #     local zip=""; local rar=""; local tar=""; local bsd=""
  415         #     case "${mimetype}" in
  416         #         application/zip) zip=1 ;;
  417         #         application/x-rar) rar=1 ;;
  418         #         application/x-7z-compressed) ;;
  419         #         *) tar=1 ;;
  420         #     esac
  421         #     { [ "$tar" ] && fn=$(tar --list --file "${FPATH}"); } || \
  422         #     { fn=$(bsdtar --list --file "${FPATH}") && bsd=1 && tar=""; } || \
  423         #     { [ "$rar" ] && fn=$(unrar lb -p- -- "${FPATH}"); } || \
  424         #     { [ "$zip" ] && fn=$(zipinfo -1 -- "${FPATH}"); } || return
  425         #
  426         #     fn=$(echo "$fn" | python -c "import sys; import mimetypes as m; \
  427         #             [ print(l, end='') for l in sys.stdin if \
  428         #               (m.guess_type(l[:-1])[0] or '').startswith('image/') ]" |\
  429         #         sort -V | head -n 1)
  430         #     [ "$fn" = "" ] && return
  431         #     [ "$bsd" ] && fn=$(printf '%b' "$fn")
  432         #
  433         #     [ "$tar" ] && tar --extract --to-stdout \
  434         #         --file "${FPATH}" -- "$fn" > "${IMAGE_CACHE_PATH}" && exit 6
  435         #     fe=$(echo -n "$fn" | sed 's/[][*?\]/\\\0/g')
  436         #     [ "$bsd" ] && bsdtar --extract --to-stdout \
  437         #         --file "${FPATH}" -- "$fe" > "${IMAGE_CACHE_PATH}" && exit 6
  438         #     [ "$bsd" ] || [ "$tar" ] && rm -- "${IMAGE_CACHE_PATH}"
  439         #     [ "$rar" ] && unrar p -p- -inul -- "${FPATH}" "$fn" > \
  440         #         "${IMAGE_CACHE_PATH}" && exit 6
  441         #     [ "$zip" ] && unzip -pP "" -- "${FPATH}" "$fe" > \
  442         #         "${IMAGE_CACHE_PATH}" && exit 6
  443         #     [ "$rar" ] || [ "$zip" ] && rm -- "${IMAGE_CACHE_PATH}"
  444         #     ;;
  445     esac
  446 }
  447 
  448 handle_mime() {
  449     mimetype="${1}"
  450     case "${mimetype}" in
  451         ## Manpages
  452         text/troff)
  453             man -l "${FPATH}"
  454             exit 0;;
  455 
  456         ## Text
  457         text/* | */xml)
  458             "$EDITOR" "${FPATH}"
  459             exit 0;;
  460             ## Syntax highlight
  461             # if [[ "$( stat --printf='%s' -- "${FPATH}" )" -gt "${HIGHLIGHT_SIZE_MAX}" ]]; then
  462             #     exit 2
  463             # fi
  464             # if [[ "$( tput colors )" -ge 256 ]]; then
  465             #     local pygmentize_format='terminal256'
  466             #     local highlight_format='xterm256'
  467             # else
  468             #     local pygmentize_format='terminal'
  469             #     local highlight_format='ansi'
  470             # fi
  471             # env HIGHLIGHT_OPTIONS="${HIGHLIGHT_OPTIONS}" highlight \
  472             #     --out-format="${highlight_format}" \
  473             #     --force -- "${FPATH}" && exit 5
  474             # pygmentize -f "${pygmentize_format}" -O "style=${PYGMENTIZE_STYLE}"\
  475             #     -- "${FPATH}" && exit 5
  476             # exit 2;;
  477 
  478         ## DjVu
  479         image/vnd.djvu)
  480             if type djvutxt >/dev/null 2>&1; then
  481                 ## Preview as text conversion (requires djvulibre)
  482                 djvutxt "${FPATH}" | eval "$PAGER"
  483                 exit 0
  484             elif type exiftool >/dev/null 2>&1; then
  485                 exiftool "${FPATH}" | eval "$PAGER"
  486                 exit 0
  487             fi
  488             exit 1;;
  489     esac
  490 }
  491 
  492 handle_fallback() {
  493     if [ "$GUI" -ne 0 ]; then
  494         if type xdg-open >/dev/null 2>&1; then
  495             nohup xdg-open "${FPATH}" >/dev/null 2>&1 &
  496             exit 0
  497         elif type open >/dev/null 2>&1; then
  498             nohup open "${FPATH}" >/dev/null 2>&1 &
  499             exit 0
  500         fi
  501     fi
  502 
  503     echo '----- File details -----' && file --dereference --brief -- "${FPATH}"
  504     exit 1
  505 }
  506 
  507 handle_blocked() {
  508     case "${MIMETYPE}" in
  509         application/x-sharedlib)
  510             exit 0;;
  511 
  512         application/x-shared-library-la)
  513             exit 0;;
  514 
  515         application/x-executable)
  516             exit 0;;
  517 
  518         application/x-shellscript)
  519             exit 0;;
  520 
  521         application/octet-stream)
  522             exit 0;;
  523     esac
  524 }
  525 
  526 handle_bin() {
  527     case "${MIMETYPE}" in
  528         application/x-executable|application/x-shellscript)
  529         clear
  530         echo '-------- Executable File --------' && file --dereference --brief -- "${FPATH}"
  531         printf "Run executable (y/N/'a'rgs)? "
  532         read -r answer
  533         case "$answer" in
  534             [Yy]* ) exec "${FPATH}";;
  535             [Aa]* )
  536                 printf "args: "
  537                 read -r args
  538                 exec "${FPATH}" "$args";;
  539             [Nn]* ) exit;;
  540         esac
  541     esac
  542 }
  543 
  544 MIMETYPE="$( file -bL --mime-type -- "${FPATH}" )"
  545 handle_extension
  546 handle_multimedia "${MIMETYPE}"
  547 handle_mime "${MIMETYPE}"
  548 [ "$BIN" -ne 0 ] && [ -x "${FPATH}" ] && handle_bin
  549 handle_blocked "${MIMETYPE}"
  550 handle_fallback
  551 
  552 exit 1