Commit initial

This commit is contained in:
Breizh 2019-10-03 13:21:17 +02:00
commit b2e8fbb920
3 changed files with 305 additions and 0 deletions

69
controller.sh Executable file
View file

@ -0,0 +1,69 @@
#!/bin/bash
# Configuration
generator=/home/files/generator.sh
max=4
export cache=/home/files/data/.thumbnails
export root=/home/files/data
# Force la génération en supprimant les index.html
# ainsi que la régénération des miniatures en les supprimant
if [[ "$1" == "-f" ]]
then
find "${root}" -name index.html -delete
rm "${cache}"/*
fi
# Mise en place de l'environnement
cd "$root"
shopt -s globstar
declare -a todo
# Pour tous les répertoires et sous-répertoires
for i in **/
do
# Récupération du chemin complet
full=$(realpath "$i")
# Exclusion(s)
if [[ "$full" =~ ^${root}/p ]]
then
continue
fi
# Analyse du répertoire
cd "$full"
# Si un index.html est déjà présent
if [[ -f "index.html" ]]
then
# Vérification de la date de modif des fichiers
for file in *
do
# Si plus récent, ou si le dossier a été modifié récemment (ex. suppresion d'un fichier)
if [[ "$file" -nt "index.html" ]] || [[ "$full" -nt "index.html" ]]
then
# Ajout du dossier à la liste. Dès qu'un fichier est concerné,
# on peut arrêter la boucle, inutile d'ajouter 10 fois le dossier
todo+=("$full")
break
fi
done
# Si pas d'index.html, on ajoute direct le dossier
else
todo+=("$full")
fi
# Retour au dossier de départ
cd - &>/dev/null
done
# S'il y a au moins un dossier, on lance le générateur sur chaque, avec $max process en parallèle
[[ "${#todo[@]}" -gt 0 ]] && for i in "${todo[@]}"; do echo $i; done | sort -r | xargs -d'\n' -L 1 -P$max $generator
# Et on génère l'index.html dossier racine
$generator
shopt -u globstar

74
controller_seq.sh Executable file
View file

@ -0,0 +1,74 @@
#!/bin/bash
# Configuration
controller=/home/files/controller.sh.bak
generator=/home/files/generator.sh
export root=/home/files/data
export cache=/home/files/data/.thumbnails
# Force la génération en supprimant les index.html
# ainsi que la régénération des miniatures en les supprimant
if [[ "$1" == "-f" ]]
then
find "${root}" -name index.html -delete
rm "${cache}"/*
shift
fi
# Mise en place de l'environnement
# Si un dossier est donné en argument, on le traite, sinon on traite la racine
olddir="$PWD"
cd "${1:-$root}"
declare -a todo
# Pour les sous-répertoires
for i in */
do
# Si aucun sous répertoire, i vaut littéralement */ provoquant des erreurs, donc on ignore
[[ ! -d "$i" ]] && continue
# Récupération du chemin complet
full=$(realpath "$i")
# Exclusion(s)
if [[ "$full" =~ ^${root}/p ]]
then
continue
fi
# Analyse du répertoire
cd "$full"
# Si un index.html est déjà présent
if [[ -f "index.html" ]]
then
# Vérification de la date de modif des fichiers
for file in *
do
# Si plus récent, ou si le dossier a été modifié récemment (ex. suppresion d'un fichier)
if [[ "$file" -nt "index.html" ]] || [[ "$full" -nt "index.html" ]]
then
# Ajout du dossier à la liste. Dès qu'un fichier est concerné,
# on peut arrêter la boucle, inutile d'ajouter 10 fois le dossier
todo+=("$full")
break
fi
done
# Si pas d'index.html, on ajoute direct le dossier
else
todo+=("$full")
fi
cd - &>/dev/null
done
# S'il y a au moins un sous-dossier, on relance le script dans chaque
# sous-dossier pour les traiter d'abord
[[ "${#todo[@]}" -gt 0 ]] && for i in "${todo[@]}"; do $controller "$i"; done
# Une fois tous les sous-dossiers traités, on génère l'index.html du dossier courant
$generator
# Et on retourne au dossier d'origine
cd "$olddir"

162
generator.sh Executable file
View file

@ -0,0 +1,162 @@
#!/bin/bash
# Récupération du chemin (passé en argument, sinon le dossier courant)
# et transformatio en chemin web (/ correspondra donc au docroot).
webpath="$(echo "${1:-$PWD}" | sed "s#^$root/##g")"
# Si jamais le path obtenu est celui de la racine, on vide la variable
# (pas très safe en cas de répétition de l'arborescence)
[[ "$webpath" =~ ^$root ]] && unset webpath
# Couleur de logs juste parce que c'est joli
blue=$(tput setaf 4)
green=$(tput setaf 2)
reset=$(tput sgr0)
# Annonce du début du traitement
echo "${blue}Start${reset} /$webpath"
# Déplacement dans le dossier à traiter
cd "${root}/${webpath}"
# Définition des différentes parties de la page
header() {
cat <<DELIM
<!DOCTYPE html>
<html lang=fr>
<head>
<title>Index de ${1}</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="/.assets/style.css">
</head>
<body>
<h2>Index de ${2}</h2>
<table id="maintable">
<tr>
<th onclick="sortTable(0)">Nom</th>
<th onclick="sortTable(1)">Taille</th>
<th onclick="sortTable(2)">Dernière modification</th>
<th onclick="sortTable(3)">Type / Aperçu</th>
</tr>
DELIM
}
row() {
cat <<DELIM
<tr>
<td><a href="${1}">${1}</a></td>
<td class="right-align" data-kbytes="${2}">${3}</td>
<td class="right-align">${4}</td>
<td>${5}</td>
</tr>
DELIM
}
footer() {
cat <<DELIM
</table>
<script src="/.assets/sort.js"></script>
</body>
</html>
DELIM
}
# Génération du header
# Le navpath est le chemin indiqué en haut de la page, qui permet de remonter
# dans l'arborescence
navpath="<a href=\"/\">files.breizh.pm</a>/"
tmp="/"
oldIFS=$IFS
IFS=/
for folder in $webpath
do
tmp+="$folder/"
navpath+="<a href=\"$tmp\">$folder</a>/"
done
IFS=$oldIFS
# Insertion du header dans le fichier
header "$webpath" "$navpath" > index.html
# Génération du tableau
preload=metadata # type de préchargement des fichiers audio
mkdir -p "$cache" # création du dossier de cache
# Pour chaque fichier ou dossier
for i in *
do
# Initialisation
unset lastmodif kbytes size thumbname mimetype
# Exclusion(s), relative(s) ou absolue(s)
if [[ "$i" == "index.html" ]] \
|| [[ "$(realpath "$i")" =~ ^$root/p ]] \
|| [[ "$(realpath "$i")" =~ ^$root/robots.txt ]]
then
continue
fi
# Date de dernière modif
lastmodif="$(stat -c "%y" "$i" | cut -d':' -f-2)"
# Taille des fichier (ignoré pour les répertoires)
if [[ -d "$i" ]]
then
kbytes=0
size="-"
else
kbytes="$(du "$i" | cut -f1)"
size="$(du -h "$i" | cut -f1)"
fi
# Hardcodage de types MIME mal détectés
[[ "$i" =~ .mp3$ ]] && mimetype="audio/mpeg"
# Détection automatique du type MIME si non hardcodé
[[ -z "$mimetype" ]] && mimetype="$(file --mime-type -b -e ascii -e compress -e tar -e cdf "$i")"
# Traitements spécifiques selon le type
case $mimetype in
audio/*)
# Pour l'audio, ajout d'un lecteur
type="<audio controls preload=\"$preload\"><source src=\"$i\" type=\"$mimetype\">$mimetype</audio>";;
image/*)
# Pour les images, une miniature de 60px de haut est créée
thumbname="$(md5sum <<<$(readlink -f "$i") | cut -d' ' -f1)-${i// /_}" # Nom sur base d'un hash pour éviter les conflits
# Si la miniature n'est pas déjà présente et que l'image est assez petite (et que c'est pas un GIF)
if [[ ! -f "${cache}/${thumbname}" ]] && [[ ${kbytes} -le 20480 ]] && [[ ! "$i" =~ .gif$ ]]
then
# Création de la miniature
convert "${i}" -strip -thumbnail 'x60>' "${cache}/${thumbname}"
fi
# Si une miniature est présente, on l'affiche
if [[ -f "${cache}/${thumbname}" ]]
then
type="<img src=\"/.thumbnails/${thumbname}\" alt=\"$mimetype\" />"
# Sinon on affiche uniquement le type
else
type="$mimetype"
fi
;;
*)
# Pour les autres fichiers, le type est affiché
type="$mimetype";;
esac
# Insertion de la ligne du tableau correspondant au fichier en cours de traitement
row "$i" "$kbytes" "$size" "$lastmodif" "$type" >> index.html
done
# Insertion du pied de page, pour terminer la page
footer >> index.html
# Annonce de la fin du traitement
echo "${green}Done${reset} /$webpath"