gendex/gendex.sh

246 lines
6.4 KiB
Bash
Raw Normal View History

2025-01-03 21:44:38 +01:00
#!/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 <https://www.gnu.org/licenses/>.
# 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
<!DOCTYPE html>
<html lang="en">
<head>
<title>%%LOCALPATH%%</title>
<meta charset="UTF-8">
<style>
body {
background-color: #000000;
color: #ffffff;
font-weight: normal;
width: 100%;
padding: 8px;
}
h1 {
font-size: 24px;
}
table {
font-size: 18px;
}
tr:hover {
background-color: #3a3a3a;
}
th, td {
border-width: 1.5px;
border-style: solid;
border-color: white;
border-collapse: collapsed;
padding-top: 1px;
padding-bottom: 1px;
padding-left: 10px;
padding-right: 10px;
}
a:link {
color: #ffffff;
}
a:visited {
color: #ffffff;
}
</style>
</head>
<body>
<h1>%%LOCALPATH%%</h1>
<table>
<tr>
<th>TYPE</th>
<th>NAME</th>
<th>MIME</th>
<th>SIZE</th>
</tr>
%%LISTING_TABLE%%
</table>
</body>
</html>
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<tr>\n<td>${TYPE}</td>\n<td><a href=\"${FILE}\">${NAME}</a></td>\n<td>${MIME}</td>\n<td>${SIZE}</td>\n</tr>"
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"