From f8f664ad2967e17c5b1f7a636a427cfb5f85f010 Mon Sep 17 00:00:00 2001 From: JeremyStarTM Date: Fri, 3 Jan 2025 21:44:38 +0100 Subject: [PATCH] Initial generation --- .gitignore | 6 ++ README.md | 63 ++++++++++++++ gendex.sh | 245 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 314 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100755 gendex.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..44b693c --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +# IDEs +.idea +.vscode + +# Output +generated-index diff --git a/README.md b/README.md new file mode 100644 index 0000000..9b7c7af --- /dev/null +++ b/README.md @@ -0,0 +1,63 @@ +# gendex +gendex is a script which generates directory listings and outputs them into an `index.html` file. + + +# Usage +`env ./gendex.sh` + +## Environment variables +gendex supports environment variables for build and output customization. +All environment variables are prefixed with `GENDEX_`. +To avoid unnecessary table bloat, we've decided to leave it out. + +For a list of data types, see [this sos!bashutils documentation page](https://bashutils.staropensource.de/introduction/datatypes/). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
VARIABLETYPEDEFAULTDESCRIPTION
`NOFANCY``bool``false`Whether to print things like the "Generation successful" message
`RECURSE``bool``false`Whether to recurse downwards and create a directory index for all directories found
`MINIFY``bool``false`Whether to minify the final output. This will just remove all newlines
`OUTPUT``str``./index.html`Where gendex should output it's generated HTML file to
`LOCALPATH``str```The local location of the specified directory. Used in the index's title and header. This value is always prefixed with a `/`
`TEMPLATE``str```The absolute location of the .html template to use. Uses the standard template if empty
+ + +# Templates +Templates are simple HTML files which form the generator's output. +To specify a custom template, pass `GENDEX_TEMPLATE` diff --git a/gendex.sh b/gendex.sh new file mode 100755 index 0000000..4232194 --- /dev/null +++ b/gendex.sh @@ -0,0 +1,245 @@ +#!/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%% +
TYPENAMEMIMESIZE
+ + +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"