"Fossies" - the Fresh Open Source Software Archive

Member "nnn-4.2/plugins/nuke" (21 Jul 2021, 18248 Bytes) of package /linux/misc/nnn-v4.2.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.1.1_vs_v4.2.

    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 (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 abspath() {
  263     case "$1" in
  264         /*) printf "%s\n" "$1";;
  265         *)  printf "%s\n" "$PWD/$1";;
  266     esac
  267 }
  268 
  269 listimages() {
  270     find -L "$(dirname "$target")" -maxdepth 1 -type f -iregex \
  271       '.*\(jpe?g\|bmp\|webp\|ico\|svg\|png\|gif\)$' -print0 | sort -z
  272 }
  273 
  274 load_dir() {
  275     target="$(abspath "$2")"
  276     count="$(listimages | grep -a -m 1 -ZznF "$target" | cut -d: -f1)"
  277 
  278     if [ -n "$count" ]; then
  279         if [ "$GUI" -ne 0 ]; then
  280             listimages | xargs -0 nohup "$1" -n "$count" --
  281         else
  282             listimages | xargs -0 "$1" -n "$count" --
  283         fi
  284     else
  285         shift
  286         "$1" -- "$@" # fallback
  287     fi
  288 }
  289 
  290 handle_multimedia() {
  291     ## Size of the preview if there are multiple options or it has to be
  292     ## rendered from vector graphics. If the conversion program allows
  293     ## specifying only one dimension while keeping the aspect ratio, the width
  294     ## will be used.
  295     # local DEFAULT_SIZE="1920x1080"
  296 
  297     mimetype="${1}"
  298     case "${mimetype}" in
  299         ## SVG
  300         # image/svg+xml|image/svg)
  301         #     convert -- "${FPATH}" "${IMAGE_CACHE_PATH}" && exit 6
  302         #     exit 1;;
  303 
  304         ## DjVu
  305         # image/vnd.djvu)
  306         #     ddjvu -format=tiff -quality=90 -page=1 -size="${DEFAULT_SIZE}" \
  307         #           - "${IMAGE_CACHE_PATH}" < "${FPATH}" \
  308         #           && exit 6 || exit 1;;
  309 
  310         ## Image
  311         image/*)
  312             if [ "$GUI" -ne 0 ]; then
  313                 if is_mac; then
  314                     nohup open "${FPATH}" >/dev/null 2>&1 &
  315                     exit 0
  316                 elif type imvr >/dev/null 2>&1; then
  317                     load_dir imvr "${FPATH}" >/dev/null 2>&1 &
  318                     exit 0
  319                 elif type sxiv >/dev/null 2>&1; then
  320                     load_dir sxiv "${FPATH}" >/dev/null 2>&1 &
  321                     exit 0
  322                 fi
  323             elif type viu >/dev/null 2>&1; then
  324                 viu -n "${FPATH}" | eval "$PAGER"
  325                 exit 0
  326             elif type img2txt >/dev/null 2>&1; then
  327                 img2txt --gamma=0.6 -- "${FPATH}" | eval "$PAGER"
  328                 exit 0
  329             elif type exiftool >/dev/null 2>&1; then
  330                 exiftool "${FPATH}" | eval "$PAGER"
  331                 exit 0
  332             fi
  333             # local orientation
  334             # orientation="$( identify -format '%[EXIF:Orientation]\n' -- "${FPATH}" )"
  335             ## If orientation data is present and the image actually
  336             ## needs rotating ("1" means no rotation)...
  337             # if [[ -n "$orientation" && "$orientation" != 1 ]]; then
  338                 ## ...auto-rotate the image according to the EXIF data.
  339                 # convert -- "${FPATH}" -auto-orient "${IMAGE_CACHE_PATH}" && exit 6
  340             # fi
  341 
  342             ## `w3mimgdisplay` will be called for all images (unless overridden
  343             ## as above), but might fail for unsupported types.
  344             exit 7;;
  345 
  346         ## PDF
  347         application/pdf)
  348             handle_pdf
  349             exit 1;;
  350 
  351         ## Audio
  352         audio/*)
  353             handle_audio
  354             exit 1;;
  355 
  356         ## Video
  357         video/*)
  358             handle_video
  359             exit 1;;
  360 
  361         #     pdftoppm -f 1 -l 1 \
  362         #              -scale-to-x "${DEFAULT_SIZE%x*}" \
  363         #              -scale-to-y -1 \
  364         #              -singlefile \
  365         #              -jpeg -tiffcompression jpeg \
  366         #              -- "${FPATH}" "${IMAGE_CACHE_PATH%.*}" \
  367         #         && exit 6 || exit 1;;
  368 
  369 
  370         ## ePub, MOBI, FB2 (using Calibre)
  371         # application/epub+zip|application/x-mobipocket-ebook|\
  372         # application/x-fictionbook+xml)
  373         #     # ePub (using https://github.com/marianosimone/epub-thumbnailer)
  374         #     epub-thumbnailer "${FPATH}" "${IMAGE_CACHE_PATH}" \
  375         #         "${DEFAULT_SIZE%x*}" && exit 6
  376         #     ebook-meta --get-cover="${IMAGE_CACHE_PATH}" -- "${FPATH}" \
  377         #         >/dev/null && exit 6
  378         #     exit 1;;
  379 
  380         ## Font
  381         # application/font*|application/*opentype)
  382         #     preview_png="/tmp/$(basename "${IMAGE_CACHE_PATH%.*}").png"
  383         #     if fontimage -o "${preview_png}" \
  384         #                  --pixelsize "120" \
  385         #                  --fontname \
  386         #                  --pixelsize "80" \
  387         #                  --text "  ABCDEFGHIJKLMNOPQRSTUVWXYZ  " \
  388         #                  --text "  abcdefghijklmnopqrstuvwxyz  " \
  389         #                  --text "  0123456789.:,;(*!?') ff fl fi ffi ffl  " \
  390         #                  --text "  The quick brown fox jumps over the lazy dog.  " \
  391         #                  "${FPATH}";
  392         #     then
  393         #         convert -- "${preview_png}" "${IMAGE_CACHE_PATH}" \
  394         #             && rm "${preview_png}" \
  395         #             && exit 6
  396         #     else
  397         #         exit 1
  398         #     fi
  399         #     ;;
  400 
  401         ## Preview archives using the first image inside.
  402         ## (Very useful for comic book collections for example.)
  403         # application/zip|application/x-rar|application/x-7z-compressed|\
  404         #     application/x-xz|application/x-bzip2|application/x-gzip|application/x-tar)
  405         #     local fn=""; local fe=""
  406         #     local zip=""; local rar=""; local tar=""; local bsd=""
  407         #     case "${mimetype}" in
  408         #         application/zip) zip=1 ;;
  409         #         application/x-rar) rar=1 ;;
  410         #         application/x-7z-compressed) ;;
  411         #         *) tar=1 ;;
  412         #     esac
  413         #     { [ "$tar" ] && fn=$(tar --list --file "${FPATH}"); } || \
  414         #     { fn=$(bsdtar --list --file "${FPATH}") && bsd=1 && tar=""; } || \
  415         #     { [ "$rar" ] && fn=$(unrar lb -p- -- "${FPATH}"); } || \
  416         #     { [ "$zip" ] && fn=$(zipinfo -1 -- "${FPATH}"); } || return
  417         #
  418         #     fn=$(echo "$fn" | python -c "import sys; import mimetypes as m; \
  419         #             [ print(l, end='') for l in sys.stdin if \
  420         #               (m.guess_type(l[:-1])[0] or '').startswith('image/') ]" |\
  421         #         sort -V | head -n 1)
  422         #     [ "$fn" = "" ] && return
  423         #     [ "$bsd" ] && fn=$(printf '%b' "$fn")
  424         #
  425         #     [ "$tar" ] && tar --extract --to-stdout \
  426         #         --file "${FPATH}" -- "$fn" > "${IMAGE_CACHE_PATH}" && exit 6
  427         #     fe=$(echo -n "$fn" | sed 's/[][*?\]/\\\0/g')
  428         #     [ "$bsd" ] && bsdtar --extract --to-stdout \
  429         #         --file "${FPATH}" -- "$fe" > "${IMAGE_CACHE_PATH}" && exit 6
  430         #     [ "$bsd" ] || [ "$tar" ] && rm -- "${IMAGE_CACHE_PATH}"
  431         #     [ "$rar" ] && unrar p -p- -inul -- "${FPATH}" "$fn" > \
  432         #         "${IMAGE_CACHE_PATH}" && exit 6
  433         #     [ "$zip" ] && unzip -pP "" -- "${FPATH}" "$fe" > \
  434         #         "${IMAGE_CACHE_PATH}" && exit 6
  435         #     [ "$rar" ] || [ "$zip" ] && rm -- "${IMAGE_CACHE_PATH}"
  436         #     ;;
  437     esac
  438 }
  439 
  440 handle_mime() {
  441     mimetype="${1}"
  442     case "${mimetype}" in
  443         ## Manpages
  444         text/troff)
  445             man -l "${FPATH}"
  446             exit 0;;
  447 
  448         ## Text
  449         text/* | */xml)
  450             "$EDITOR" "${FPATH}"
  451             exit 0;;
  452             ## Syntax highlight
  453             # if [[ "$( stat --printf='%s' -- "${FPATH}" )" -gt "${HIGHLIGHT_SIZE_MAX}" ]]; then
  454             #     exit 2
  455             # fi
  456             # if [[ "$( tput colors )" -ge 256 ]]; then
  457             #     local pygmentize_format='terminal256'
  458             #     local highlight_format='xterm256'
  459             # else
  460             #     local pygmentize_format='terminal'
  461             #     local highlight_format='ansi'
  462             # fi
  463             # env HIGHLIGHT_OPTIONS="${HIGHLIGHT_OPTIONS}" highlight \
  464             #     --out-format="${highlight_format}" \
  465             #     --force -- "${FPATH}" && exit 5
  466             # pygmentize -f "${pygmentize_format}" -O "style=${PYGMENTIZE_STYLE}"\
  467             #     -- "${FPATH}" && exit 5
  468             # exit 2;;
  469 
  470         ## DjVu
  471         image/vnd.djvu)
  472             if type djvutxt >/dev/null 2>&1; then
  473                 ## Preview as text conversion (requires djvulibre)
  474                 djvutxt "${FPATH}" | eval "$PAGER"
  475                 exit 0
  476             elif type exiftool >/dev/null 2>&1; then
  477                 exiftool "${FPATH}" | eval "$PAGER"
  478                 exit 0
  479             fi
  480             exit 1;;
  481     esac
  482 }
  483 
  484 handle_fallback() {
  485     if [ "$GUI" -ne 0 ]; then
  486         if type xdg-open >/dev/null 2>&1; then
  487             nohup xdg-open "${FPATH}" >/dev/null 2>&1 &
  488             exit 0
  489         elif type open >/dev/null 2>&1; then
  490             nohup open "${FPATH}" >/dev/null 2>&1 &
  491             exit 0
  492         fi
  493     fi
  494 
  495     echo '----- File details -----' && file --dereference --brief -- "${FPATH}"
  496     exit 1
  497 }
  498 
  499 handle_blocked() {
  500     case "${MIMETYPE}" in
  501         application/x-sharedlib)
  502             exit 0;;
  503 
  504         application/x-shared-library-la)
  505             exit 0;;
  506 
  507         application/x-executable)
  508             exit 0;;
  509 
  510         application/x-shellscript)
  511             exit 0;;
  512 
  513         application/octet-stream)
  514             exit 0;;
  515     esac
  516 }
  517 
  518 handle_bin() {
  519     case "${MIMETYPE}" in
  520         application/x-executable|application/x-shellscript)
  521         clear
  522         echo '-------- Executable File --------' && file --dereference --brief -- "${FPATH}"
  523         printf "Run executable (y/N/'a'rgs)? "
  524         read -r answer
  525         case "$answer" in
  526             [Yy]* ) exec "${FPATH}";;
  527             [Aa]* )
  528                 printf "args: "
  529                 read -r args
  530                 exec "${FPATH}" "$args";;
  531             [Nn]* ) exit;;
  532         esac
  533     esac
  534 }
  535 
  536 MIMETYPE="$( file -bL --mime-type -- "${FPATH}" )"
  537 handle_extension
  538 handle_multimedia "${MIMETYPE}"
  539 handle_mime "${MIMETYPE}"
  540 [ "$BIN" -ne 0 ] && [ -x "${FPATH}" ] && handle_bin
  541 handle_blocked "${MIMETYPE}"
  542 handle_fallback
  543 
  544 exit 1