Forum darktable FR
Exécution purge_non_existing_images avec Windows - Version imprimable

+- Forum darktable FR (https://forums.darktable.fr)
+-- Forum : Utilisation de darktable (https://forums.darktable.fr/forumdisplay.php?fid=97)
+--- Forum : Installation (https://forums.darktable.fr/forumdisplay.php?fid=101)
+--- Sujet : Exécution purge_non_existing_images avec Windows (/showthread.php?tid=5747)



Exécution purge_non_existing_images avec Windows - Scap - 25-05-21

Bonjour,

A force de persévérance j'ai fini pas réussir à lancer purge_non_existing_images sous Windows 10.

Je vais détailler ici les étapes afin d'aider ceux qui comme moi utilisent cet OS et qui peinent à faire fonctionner le script.

1. Suivre les instructions de Dready_ras, étapes 1 à 3.
2. Suivre les instructions de ce lien suivant, à partir du paragraphe "Exécuter le script Shell sur Windows 10 avec Git Bash"
3. Suivre les instructions de cette vidéo. Il faut bien faire attention à ajouter le chemin vers le dossier dans la variable "path" et pas ailleurs.
4. Localiser le script. il se trouve normalement sous "C:\Program Files\darktable\share\darktable\tools\"
5. Ouvrir git bash
6. Glisser le script dans git bash et valider

Attention, ça ne fonctionnera normalement pas car le script va chercher la librairie ici : "D:\Users\votre_username\.config\darktable\" or, la librairie est en fait sous "D:\User\votre_username\AppData\Local\darktable". En tout cas c'était comme ça pour moi, par conséquent, si c'est aussi le cas pour vous, il faut :
7. Modifier la ligne 20 du script de la façon suivante.

Code :
configdir="${HOME}/AppData/Local/darktable"

Enfin, il faut recommencer l'étape 6 et le script devrait fonctionner.

Il faut ajouter --purge à la fin du chemin affiché pour purger la base de données.

Chez moi ça supprime malheureusement toute la base... il y a un problème dans le script au niveau du test

Code :
    if ! [ -f "$path" ]

Pour un raison que j'ignore encore cette condition est toujours vraie, donc tous les fichiers de la base sont considérés non-existants...
Peut-être que le problème se situe au niveau de cette ligne qui ne fonctionne pas pareil sous Windows ?

Code :
QUERY="SELECT images.id, film_rolls.folder || '/' || images.filename FROM images JOIN film_rolls ON images.film_id = film_rolls.id"

Si quelqu'un a une idée je suis preneur Smile

---

EDIT

Voici ma solution pour utiliser purge_non_existing_images sous Windows 10
J'ai modifié la ligne 20 (configdir) et modifié la boucle While qui lit la base de donnée pour supprimer le CR sur les paths lus.
Maintenant le script fonctionne pour moi Smile

Code :
#!/bin/bash

#
# Usage: purge_non_existing_images [-p]
#        -p  do the purge, otherwise only display non existing images
#

if ! command -v sqlite3 >/dev/null
then
    echo "error: please install sqlite3 binary".
    exit 1
fi

if pgrep -x "darktable" >/dev/null
then
    echo "error: darktable is running, please exit first"
    exit 1
fi

#configdir="${HOME}/.config/darktable"
configdir="${HOME}/AppData/Local/darktable"
DBFILE="${configdir}/library.db"
dryrun=1
library=""

# remember the command line to show it in the end when not purging
commandline="$0 $*"

# handle command line arguments
while [ "$#" -ge 1 ]
do
    option="$1"
    case "$option" in
    -h | --help)
        echo "Delete non existing images from darktable's database"
        echo "Usage:   ${0} [options]"
        echo ""
        echo "Options:"
        echo "  -c|--configdir <path>    path to the darktable config directory"
        echo "                           (default: '${configdir}')"
        echo "  -l|--library <path>      path to the library.db"
        echo "                           (default: '${DBFILE}')"
        echo "  -p|--purge               actually delete the tags instead of just finding them"
        exit 0
        ;;
    -l | --library)
        library="$2"
        shift
        ;;
    -c | --configdir)
        configdir="$2"
        shift
        ;;
    -p | --purge)
        dryrun=0
        ;;
    *)
        echo "warning: ignoring unknown option ${option}"
        ;;
    esac
    shift
done

DBFILE="$configdir/library.db"

if [ "$library" != "" ]
then
    DBFILE="$library"
fi

if [ ! -f "$DBFILE" ]
then
    echo "error: library db '${DBFILE}' doesn't exist"
    exit 1
fi

QUERY="SELECT images.id, film_rolls.folder || '/' || images.filename FROM images JOIN film_rolls ON images.film_id = film_rolls.id"

echo "Removing the following non existent file(s):"

while read -r -u 9 id path
do

    pathTMP=$(echo $path | tr -d '\r')
    #echo "a $pathTMP b"

    if ! [ -f "$pathTMP" ]
    then
        echo "  ${pathTMP} with ID = ${id}"
        ids="${ids+${ids},}${id}"
    fi
done 9< <(sqlite3 -separator $'\t' "$DBFILE" "$QUERY")

if [ "$dryrun" -eq 0 ]
then
    for table in images meta_data
    do
        sqlite3 "$DBFILE" <<< "DELETE FROM ${table} WHERE id IN ($ids)"
    done

    for table in color_labels history masks_history selected_images tagged_images history_hash module_order
    do
        sqlite3 "$DBFILE" <<< "DELETE FROM ${table} WHERE imgid in ($ids)"
    done

    # delete now-empty film rolls
    sqlite3 "$DBFILE" "DELETE FROM film_rolls WHERE NOT EXISTS (SELECT 1 FROM images WHERE images.film_id = film_rolls.id)"
    sqlite3 "$DBFILE" "VACUUM; ANALYZE"
else
    echo
    echo Remove following now-empty filmrolls:
    sqlite3 "$DBFILE" "SELECT folder FROM film_rolls WHERE NOT EXISTS (SELECT 1 FROM images WHERE images.film_id = film_rolls.id)"

    echo
    echo to really remove non existing images from the database call:
    echo "${commandline} --purge"
fi



RE: Exécution purge_non_existing_images avec Windows - jpverrue - 25-05-21

(25-05-21, 17:26)Scap a écrit : ...
Code :
    if ! [ -f "$path" ]

C'est bien là que ça se passe ce test vérifie que le fichier référencé dans la BdD par le chemin récupéré dans la variable $path existe bien. S'il n'existe pas, il est supprimé dans la BdD.

Il est donc probable que la façon dont le chemin est enregistré dans la BdD ne correspond pas exactement à ce qu'il est en réalité dans le système (problème de compatibilité Linux/Windows). Pour en avoir le cœur net il te suffit d'afficher $path juste avant le test avec une ligne comme celle-ci : echo $path
Je crois que tu verras ce qui cloche et doit être ajusté


RE: Exécution purge_non_existing_images avec Windows - Scap - 26-05-21

Oui je pensais quelque chose comme ça, problème de compatibilité au niveau des chemins

J'ai ajouté echo "${path}" après le "Do" ligne 83 et le chemin suivant s'affiche dans le terminal git bash :
D:\/MonImage.jpg

Dans la base de donnée
La variable film_rolls.folder contient  : D:\
La variable images.filename contient : MonImage.jpg

J'ai donc tenté de modifier la ligne QUERY de cette façon
Code :
QUERY="SELECT images.id, film_rolls.folder || images.filename FROM images JOIN film_rolls ON images.film_id = film_rolls.id"

Mais le fichier n'existe pas selon le test...

J'ai fait un autre test, j'ai exécuté le script suivant

Code :
echo "start test"
pathTest="/d/MonImage.jpg"
if [ ! -f "$pathTest" ]
then
    echo "$pathTest does not exist."
else
    echo "$pathTest exists."
fi
echo "end test"

Et le terminal affiche : /d/MonImage.jpg exists.

J'ai ensuite testé en modifiant la ligne QUERY de la façon suivante :
Code :
QUERY="SELECT images.id, '/d/' || images.filename FROM images JOIN film_rolls ON images.film_id = film_rolls.id"

Et j'ai encore le même problème... le fichier n'existe pas selon le if

....

Voici un autre essai dont le résultat m'étonne

Code :
#QUERY="SELECT images.id, film_rolls.folder || '/' || images.filename FROM images JOIN film_rolls ON images.film_id = film_rolls.id"
QUERY="SELECT images.id, '/d/' || images.filename FROM images JOIN film_rolls ON images.film_id = film_rolls.id"

echo "Removing the following non existent file(s):"

echo "start test"
pathTest="D:\MonImage.jpg"
##echo "/$pathTest" | sed -e 's/\\/\//g' -e 's/://'
if [ ! -f "$pathTest" ]
then
    echo "$pathTest does not exist."
else
    echo "$pathTest exists."
fi
pathTest="/d/MonImage.jpg"
if [ ! -f "$pathTest" ]
then
    echo "$pathTest does not exist."
else
    echo "$pathTest exists."
fi
echo "end test"

while read -r -u 9 id path
do       

    if [ ! -f "$path" ]
    then
        echo "Not ok ${path}"
        ids="${ids+${ids},}${id}"
    fi
done 9< <(sqlite3 -separator $'\t' "$DBFILE" "$QUERY")

Résultat dans le terminal..

Removing the following non existent file(s):
start test
D:\MonImage.jpg exists.
/d/MonImage.jpg exists.
end test
Not ok /d/MonImage.jpg


Je ne comprends pas  Confused


RE: Exécution purge_non_existing_images avec Windows - Scap - 26-05-21

J'ai trouvé que le problème se situe au niveau de la variable "path"



Lorsqu'on lit la base de donnée et qu'on écrit les lignes dans un fichier, il y a un CRLF à la fin de chaque path

Code :
while read -r -u 9 id path
do
    echo "Write ${id} ${path}"
    echo  "$path" >> "D:\file.txt"
done 9< <(sqlite3 -separator $'\t' "$DBFILE" "$QUERY")

Par contre, lorsque j'écris moi même



Code :
echo  "D:\MonImage1" >> "D:\file.txt"
echo  "D:\MonImage2" >> "D:\file.txt"
echo  "D:\MonImage3" >> "D:\file.txt"


Il y a un LF à la fin de chaque ligne
Le test if ! [[ -f $path ]] ne fonctionne apparemment pas lorsqu'il y a un CRLF à la fin d'un string...

J'ai cherché un moment mais je n'ai malheureusement pas encore réussi à remplacer les CRLF en LF à la fin de chaque path lu depuis la db...


RE: Exécution purge_non_existing_images avec Windows - Scap - 26-05-21

J'ai trouvé !!!

Je mets ma solution dans le premier message


RE: Exécution purge_non_existing_images avec Windows - jpverrue - 26-05-21

Bravo pour la recherche ! Effectivement les fins de lignes sont différentes entre Windows et le monde Unix. Sous Windows le fin de lignes sont constituées de CR+LF alors que dans le monde Unix, elles sont constituées d'un simple LF.

Ce qui est étonnant, c'est que pendant l'exécution du script il me semble que tu es dans un environnement Unix, donc ce problème CFLF ≠ LF ne devrait pas exister. N'y a-t-il pas une option pour lancer bash ?

Dans le lien cité en 2), vers le milieu de la page, il est mentionné l'exécution d'un script avec WSL. WSL est la partie de Linux intégrée de base dans Windows https://fr.wikipedia.org/wiki/Windows_Subsystem_for_Linux. Ceci devrait te permettre d'éviter les manips avec Git et Git bash. Et peut-être régler le problème du CFLF ≠ LF. À tester ...


RE: Exécution purge_non_existing_images avec Windows - Scap - 27-05-21

Merci Smile

Je crois qu'il y a un fichier de config pour que git bash gère le CR mais je n'ai pas compris comment l'utiliser.. j'ai abandonné cette solution.
J'avais aussi tenté l'activation du sous-système Windows pour Linux mais j'ai eu un message d'erreur de Windows à ce moment, j'ai abandonné aussi assez vite, il faudrait creuser à l'occasion