#!/usr/bin/env bash # STAROPENSOURCE GENDEX SOURCE FILE # Copyright (c) 2024 The StarOpenSource gendex Authors # Licensed under the GNU Affero General Public License v3 # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # Download bashutils (if missing) if [ ! -d "/tmp/bashutils-gendex" ]; then echo "Cloning bashutils" ( set -euo pipefail git clone "https://git.staropensource.de/StarOpenSource/bashutils" "/tmp/bashutils-gendex" cd "/tmp/bashutils-gendex" git checkout "08d7046474d9b40f49e33e4788d6ed693bdce63e" ) || exit 1 fi # Load bashutils source /tmp/bashutils-gendex/bashutils.sh # Enable strict mode # bashutils unfortunately doesn't yet support the full strict mode set -o pipefail # Utility methods # shellcheck disable=SC2001 function file2env() { echo "${1}" | sed "s/[^A-Z0-9]/__/gI"; } function default_template() { cat << EOF %%LOCALPATH%%

%%LOCALPATH%%

%%LISTING_TABLE%%
TYPE NAME MIME SIZE
EOF } # Set defaults set_undefined GENDEX_NOFANCY "false" set_undefined GENDEX_RECURSE "false" set_undefined GENDEX_MINIFY "true" set_undefined GENDEX_OUTPUT "./index.html" set_undefined GENDEX_LOCALPATH "/" set_undefined GENDEX_TEMPLATE "" # Load template verb "Loading template" if [ -z "${GENDEX_TEMPLATE}" ]; then INDEX="$(default_template)" else INDEX="$(cat "${GENDEX_TEMPLATE}")" fi # Create output file verb "(Re-)Creating output file at '${GENDEX_OUTPUT}'" rm -rf "${GENDEX_OUTPUT}" mkdir -p "$(dirname "${GENDEX_OUTPUT}")" # Generate listing verb "Generating listing" declare -a FILES # -> Iterate over all files # and determine their properties diag "Discovering directory" for FILE in *; do # Determine environment variable name ENVVAR=$(file2env "${FILE}") # Determine file type # These will overwrite each other [ -a "${FILE}" ] && TYPE="???" [ -d "${FILE}" ] && TYPE="dir" [ -f "${FILE}" ] && TYPE="file" [ -b "${FILE}" ] && TYPE="block" [ -c "${FILE}" ] && TYPE="char" [ -h "${FILE}" ] && TYPE="symlink" [ -S "${FILE}" ] && TYPE="socket" # Determine MIME type MIME=$(file -b --mime-type "${FILE}") # Determine file size in bytes if [ -d "${FILE}" ]; then SIZE="-" else SIZE=$(wc -c "${FILE}" | cut -d' ' -f1) fi # Export properties export "FILES_${ENVVAR}_TYPE=${TYPE}" export "FILES_${ENVVAR}_MIME=${MIME}" export "FILES_${ENVVAR}_SIZE=${SIZE}" # Add to FILES array FILES+=( "${FILE}" ) done # -> Create semicolon-comma-separated string diag "Generating semicolon-comma-separated string" unset "LISTING_COMBINED" for FILE in "${FILES[@]}"; do ENVVAR=$(file2env "${FILE}") TYPE=$( TMP="FILES_${ENVVAR}_TYPE" echo "${!TMP}" ) MIME=$( TMP="FILES_${ENVVAR}_MIME" echo "${!TMP}" ) SIZE=$( TMP="FILES_${ENVVAR}_SIZE" echo "${!TMP}" ) export "LISTING_COMBINED=${LISTING_COMBINED}:name=${FILE},type=${TYPE},mime=${MIME},size=${SIZE}" done # -> Create table diag "Generating table" unset "LISTING_TABLE" for FILE in "${FILES[@]}"; do ENVVAR=$(file2env "${FILE}") TYPE=$( TMP="FILES_${ENVVAR}_TYPE" echo "${!TMP}" ) NAME=$( echo -n "${FILE}" [ "${TYPE}" == "dir" ] && echo -n "/" ) MIME=$( TMP="FILES_${ENVVAR}_MIME" echo "${!TMP}" ) SIZE=$( TMP="FILES_${ENVVAR}_SIZE" echo "${!TMP}" ) LISTING_TABLE="${LISTING_TABLE}\n\n${TYPE}\n${NAME}\n${MIME}\n${SIZE}\n" done # Process template verb "Processing template" INDEX="$(echo "${INDEX}" | sed "s/%%LOCALPATH%%/${GENDEX_LOCALPATH//\//\\/}/g" | sed "s/%%LISTING_TABLE%%/${LISTING_TABLE//\//\\/}/g")" # Minify output if [ "${GENDEX_MINIFY}" == "true" ]; then INDEX="$(echo "${INDEX}" | tr -d '\n' | awk '{$1=$1};1')" fi # Write final output verb "Writing final output" echo "${INDEX}" > index.html # Recurse downwards if [ "${GENDEX_RECURSE}" == "true" ]; then GENDEX=$(realpath "${0}") for FILE in *; do if [ -d "${FILE}" ]; then ( info "Recursing into '${FILE}'" cd "${FILE}" BASHUTILS_SUBSHELL="$(( BASHUTILS_SUBSHELL + 1 ))" GENDEX_NOFANCY="true" GENDEX_LOCALPATH="${GENDEX_LOCALPATH}${FILE}/" "${GENDEX}" || true ) fi done fi # Print completion message [ "${GENDEX_NOFANCY}" == "false" ] && info "GENERATION SUCCESSFUL\ngendex successfully generated a directory listing\nfor this directory. You can see it at:\n'${GENDEX_OUTPUT}'\n\nThank you for using gendex!\nYou can find the full source code at:\nhttps://git.staropensource.de/Infrastructure/gendex"