#!/bin/bash _cache_thumbnail() { thumbnail_dir="${XDG_CACHE_HOME:-$HOME/.cache}/thumbnails" [ ! -d "${thumbnail_dir}" ] && mkdir -p "${thumbnail_dir}" tmpfile="${thumbnail_dir}/$(stat -c '%n%i%F%s%Y' -- "$(readlink -f "$2")" | sha256sum | awk '{print $1}').jpg" if [ ! -f "$tmpfile" ]; then case "$1" in image) convert -- "$2"'[0]' "$tmpfile" ;; video) ffmpegthumbnailer -i "$2" -o "$tmpfile" -s 0 ;; font) read -r -d '' font_preview_text <<-EOF ABCDEFGHIJKLM NOPQRSTUVWXYZ abcdefghijklm nopqrstuvwxyz 1234567890 !@$\%<>(){}[] == != => <= 愛してるおかえりなさい EOF convert -size 900x900 xc:"{{ colors.background }}" \ -gravity center \ -pointsize 40 \ -font "$2" \ -fill "{{ colors.white2 }}" \ -annotate +0+0 "$font_preview_text" \ -flatten "$tmpfile" ;; esac fi # Return the location printf "%s" "$tmpfile" } _preview_markdown() { mdcat "$1" || glow -s ~/.config/glow/styles/{{ theme }}.json "$1" || lowdown -t term "$1" } _preview_image() { chafa --animate=off --polite=on --size="$2"x"$3" "$1" || chafa --animate=off --polite=on --size="$2"x"$3" "$(_cache_thumbnail image "$1")" } _preview_video() { _preview_image "$(_cache_thumbnail video "$1")" "$2" "$3" } _preview_font() { _preview_image "$(_cache_thumbnail font "$1")" "$2" "$3" } # Take 2 additional arguments as width and height (rows/cols) FILE="$1" WIDTH="$2" HEIGHT="$3" mimetype=$(file --dereference --brief --mime-type -- "$FILE") filename="$(basename "$FILE")" if [[ $mimetype == inode/directory ]]; then # Don't preview the inode ../ if [ -z "${FILE##*/..*}" ]; then echo "" else lsd -1FAL --group-dirs first --icon always --color always "$FILE" fi exit fi if [[ $mimetype == @(image/vnd.djvu?(+multipage)|image/x-djvu) ]]; then djvutxt "$FILE" || exiftool "$FILE" exit fi if [[ $mimetype == image/* ]]; then _preview_image "$FILE" "$WIDTH" "$HEIGHT"; exit fi if [[ $mimetype == video/* ]]; then _preview_video "$FILE" "$WIDTH" "$HEIGHT"; exit fi if [[ $mimetype == audio/* ]]; then fprobe -hide_banner -pretty "$FILE" || exiftool "$FILE" exit fi if [[ $mimetype == @(font/*|application/x-font*|application/vnd.ms-opentype) ]]; then _preview_font "$FILE" "$WIDTH" "$HEIGHT"; exit fi if [[ $mimetype == application/pdf ]]; then mutool draw -F txt -i -- "$FILE" 1-10 || pdftotext -l 10 -nopgbrk -q -- "$FILE" - || exiftool "$FILE" exit fi if [[ $mimetype == application/postscript ]]; then pstotext "$FILE" || ps2ascii "$FILE" || exiftool "$FILE" exit fi if [[ $mimetype == @(text/?(x-)troff|application/x-troff-*) ]]; then man "$FILE" | col -b exit fi if [[ $mimetype == application/vnd.oasis.opendocument.text* ]]; then odt2txt "$FILE" || (pandoc -s -t markdown -- "$FILE" | _preview_markdown -) exit fi if [[ $mimetype == application/epub+zip ]]; then epub2txt "$FILE" || exiftool "$FILE" exit fi if [[ $mimetype == @(application/x-fictionbook+xml|application/vnd.openxmlformats-officedocument.wordprocessingml.document) ]]; then pandoc -s -t markdown -- "$FILE" | _preview_markdown - exit fi if [[ $mimetype == application/x-bittorrent ]]; then dumptorrent -v "$FILE" || transmission-show -- "$FILE" || exiftool "$FILE" exit fi if [[ $mimetype == @(application/zip|application/zlib|application/java-archive|application/vnd.android.package-archive|application/x-zip*) ]]; then zip -sf "$FILE" || zipinfo "$FILE" || bsdtar -tf "$FILE" exit fi if [[ $filename == @(*.tar.@(zst|gz|lz|lzma|lzo|xz|Z)|*.tb2|*.tz2|*.tbz|*.tbz2|*.taz|*.tgz|*.tlz|*.txz|*.tZ|*.taZ|*.tzst) ]] || [[ $mimetype == @(application/x-?(g)tar*|application/*-compressed-tar) ]]; then tar -tvf "$FILE" || bsdtar -tf "$FILE" exit fi if [[ $mimetype == application/zstd ]]; then zstd -l "$FILE"; exit fi if [[ $mimetype == @(application/x-xz*|application/*-xz-compressed) ]]; then xz --list "$FILE" || bsdtar -tf "$FILE" exit fi if [[ $mimetype == @(application/vnd.rar|application/vnd.comicbook-rar|application/x-rar*) ]]; then unrar lt -p- -- "$FILE" || bsdtar -tf "$FILE" exit fi if [[ $mimetype == application/x-7z-compressed ]]; then 7z l -p -- "$FILE" || bsdtar -tf "$FILE" exit fi if [[ $mimetype == @(application/vnd.efi.iso|application/x-*-rom|application/x-compressed-iso|application/x*-iso?(9660)-?(app)image) ]]; then isoinfo -f -i "$FILE" || bsdtar -tf "$FILE" exit fi if [[ $mimetype == application/x-cpio* ]]; then cpio -tF "$FILE" || bsdtar -tf "$FILE" exit fi if [[ $mimetype == application/?(x-)gzip ]]; then bsdtar -tf "$FILE" || gzip -l "$FILE" exit fi if [[ $mimetype == @(application/vnd.ms-cab-compressed|application/x-archive|application/?(x-)bzip*|application/x-lzma|application/x-lzip|application/x-lha|application/x-lzh-compressed|application/x-lhz|application/x-lzop|application/x-lz4|application/x-lrzip) ]]; then bsdtar -tf "$FILE"; exit fi if [[ $mimetype == application/x-ipynb+json ]]; then notedown --from notebook "$FILE" --to markdown | _preview_markdown - exit fi if [[ $mimetype == text/plain ]] && [[ $filename == *.json?(c|5) ]] || [[ $mimetype == @(application/json*|application/*+json) ]]; then jq . "$FILE" | gojq -C . "$FILE" || jaq --color=always . "$FILE" || bat --style=plain --color=always "$FILE" || python3 -m json.tool -- "$FILE" exit fi if [[ $mimetype == text/plain ]] && [[ $filename == *.@(md|mkd|markdown) ]] || [[ $mimetype == text/markdown ]]; then _preview_markdown "$FILE"; exit fi if [[ $mimetype == @(text/*|application/javascript|application/xhtml+xml) ]]; then bat --style plain --color=always "$FILE"; exit fi # Try to get something out of exiftool # NOTE: exiftool always prints what it can retrieve to stdout, so suppress the message here metadata="$(exiftool "$FILE")" if ! (echo "$metadata" | awk -F':' '{print $1}' | grep -q '^Error'); then echo "$metadata" else echo '----- File Type Classification -----' && file --dereference --brief -- "$FILE" fi