#!/bin/bash # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 source "$(dirname "$0")/lib/ulib/ulib" || exit 1 urequire DEFAULTS function display_help() { uecho "$scriptname: classer des fichiers selon certains règles Les règles sont spécifiées dans le fichier ~/etc/default/ufile Dans ce fichier, le tableau RULES contient des règles qui sont chacune de la forme pattern:destdir[:renamef] - pattern est au format glob et identifie les fichiers auxquels s'applique la règle - destdir est le répertoire de destination dans lequel classer le fichier - renamef est une fonction qui permet de supporter le renommage d'un fichier lors de son classement. Sa signature est 'renamef filename pf destdir' où filename est le nom du fichier source, pf son chemin complet et destdir la valeur de destdir mentionnée dans la règle. La fonction doit définir la variable dest qui est le nouveau nom. Si la fonction retourne un code d'erreur autre que zéro, la règle est ignorée. Si le nouveau nom contient un chemin, destdir est ignoré et le fichier est déplacé dans le répertoire spécifié. USAGE $scriptname [options] OPTIONS -c, --config CONFIG Utiliser le fichier de configuration spécifié au lieu de la valeur par défaut ~/etc/default/ufile -n, --fake Afficher les opérations qui seraient faites -l, --list Lister les règles définies -e, --edit Lancer un éditeur sur le fichier de configuration" } function joinp() { # afficher le chemin $1/$2 local pf="$1" [ -n "$2" -a "${pf%/}" == "$pf" ] && pf="$pf/" pf="$pf${2#/}" echo "$pf" } args=(% --help '$exit_with display_help' -c:,--config: config= -n,--fake fake=1 -l,--list action=list -e,--edit action=edit --file action=file ) parse_args "$@"; set -- "${args[@]}" [ -n "$action" ] || action=file ## charger toutes les règles RULES=() INCLUDES=() if [ -n "$config" ]; then if [ "$action" != edit ]; then # le fichier doit exister, sauf en mode édition où il sera créé s'il # n'existe pas déjà [ -f "$config" ] || die "$config: fichier introuvable" fi if [ -f "$config" ]; then source "$config" || die "$config: erreur lors de la lecture du fichier" fi else set_defaults ufile fi array_copy rules RULES for include in "${INCLUDES[@]}"; do if [ -f "$include" ]; then RULES=() source "$include" array_extend rules RULES else ewarn "$include: fichier introuvable" fi done array_copy RULES rules ## actions particulières if [ "$action" == list ]; then echo "# $(echo_seta2 INCLUDES)" array_to_lines RULES exit 0 elif [ "$action" == edit ]; then [ -n "$config" ] || setx config=get_user_defaults_file ufile if [ ! -f "$config" ]; then einfo "Le fichier $(ppath "$config") n'existe pas. Il sera créé avec un contenu par défaut" mkdirof "$config" || die cp "$scriptdir/lib/default/ufile" "$config" fi "${EDITOR:-vi}" "$config" exit $? else die "bug: $action: action non implémentée" fi ## classement des fichiers if [ -n "$fake" ]; then function docmd() { qvals "$@"; } else function docmd() { "$@"; } fi [ $# -gt 0 ] || die "Vous devez spécifier des fichiers à classer" [ ${#RULES[*]} -gt 0 ] || die "Vous devez spécifier des règles pour le classement des fichiers dans ~/etc/default/ufile" # vérifier les règles for rule in "${RULES[@]}"; do splitpair "$rule" pattern r2 splitpair "$r2" destdir r3 splitpair "$r3" renamef r4 if [ -z "$destdir" -o "${destdir#"~/"}" != "$destdir" ]; then : elif [ "${destdir#/}" == "$destdir" ]; then ewarn "$rule: règle potentiellement problématique: destdir devrait être absolu" fi done # faire le classement effectif for file in "$@"; do [ -f "$file" -o -n "$fake" ] || { eerror "$file: fichier introuvable. il sera ignoré" continue } setx pf=abspath "$file" setx dir=dirname -- "$pf" setx filename=basename -- "$pf" found= for rule in "${RULES[@]}"; do splitpair "$rule" pattern r2 splitpair "$r2" destdir r3 splitpair "$r3" renamef r4 if [ "${destdir#"~/"}" != "$destdir" ]; then destdir="$HOME/${destdir#"~/"}" fi eval "[[ \"\$filename\" == $(qwc "$pattern") ]]" || continue destname="$filename" if [ -n "$renamef" ]; then dest= "$renamef" "$filename" "$pf" "$destdir" || continue if [ -n "$dest" ]; then if [[ "$dest" == */* ]]; then setx dest=abspath "$dest" setx destdir=dirname -- "$dest" setx destname=dirname -- "$dest" else destname="$dest" fi fi fi if [ -z "$destdir" ]; then eerror "$rule: règle invalide: destdir est vide" break fi setx dest=joinp "$destdir" "$destname" estep "$filename --> $dest" ask_yesno -i "Voulez-vous continuer?" O || { found=x; break; } docmd mkdir -p "$destdir" || die "$destdir: impossible de créer le répertoire" docmd mv -i "$file" "$dest" || die "problème lors du déplacement du fichier" found=1 break done if [ -z "$found" ]; then ewarn "$file: aucune correspondance n'a été trouvée" fi done