246 lines
6.4 KiB
Bash
246 lines
6.4 KiB
Bash
|
#!/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"
|