Jump to content

[SCRIPT] Trier des photos d'un repertoire


Recommended Posts

Alors voici un script sans grande conviction mais qui pourrait servir a d'autres :

]#!/bin/bash

#	 Author : 16aR
#
#	 This program is free software; you can redistribute it and/or modify
#	 it under the terms of the GNU General Public License as published by
#	 the Free Software Foundation; either version 2 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 General Public License for more details.
# 
#	 You should have received a copy of the GNU General Public License
#	 along with this program; if not, write to the Free Software
#	 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

#Necessite : 
#rsync
#exif

DIRECTORY_TO_CHECK="."
# Si on a au moins un argument, alors on assigne cet argument a DIRECTORY_TO_CHECK
if [ $# -ge 1 ]; then
DIRECTORY_TO_CHECK="$1"
fi


# Internal Field separator : treeeeeeees pratique (pour les noms de fichiers avec des espaces !)
IFS="
"

## rechercher des fichiers jpeg sans qu'ils aient l'extension *.jpg (genre dans un lost+found ...)
#FILES=$(find $DIRECTORY_TO_CHECK -type f -exec file -i {} \; | grep "image/jpeg" | cut -d: -f1)

FILES=$(find $DIRECTORY_TO_CHECK -iname "*.jpg")

PHOTOS_ROOT="${PHOTOS_ROOT:=$HOME/images/photos}"
TMPDIR="/tmp/importPhotos/0"
PHOTOS_ROOT="$HOME/tmp/photos"

#Gère le lancement simultané d'import (meme si ce n'est pas top de le lancer en plusieurs fois niveau performances...)
while [ -d ${TMPDIR} ]
do
	INCREMENT=$(expr ${INCREMENT:=0} + 1)

	TMPDIR="${TMPDIR}/../${INCREMENT}"
done
mkdir -p "${TMPDIR}"




function getYear
{
echo $1 | cut -d: -f1
}

function getMonth
{
	echo $1 | cut -d: -f2
}

function getDay
{
	echo $1 | cut -d: -f3 
}


function onEnd
{
rm -rf ${TMPDIR}
}

function processEachFile
{

IFS="
"

FILE=$1

DATE_VALUE=$(exif -t 0x0132 ${FILE} |grep "Value" | cut -d: -f2-4 | cut -d" " -f1-2 | sed -e "s/ //g")

YEAR=$(getYear ${DATE_VALUE})
MONTH=$(getMonth ${DATE_VALUE})
DAY=$(getDay ${DATE_VALUE})

IFS="
"

echo ${FILE} >> ${TMPDIR}/liste-${DAY}_${MONTH}_${YEAR}
IFS=" "

}

IFS="
"

# Récupère les informations EXIF de chaque fichier listé
for file in $FILES
do
echo "Getting EXIF Info:" $file
processEachFile $file
done

IFS="
"
# lance les transferts de liste avec rsync
for listeRsync in $(ls ${TMPDIR})
do
DAY=$(echo ${listeRsync} | cut -d- -f2 | cut -d_ -f1)
MONTH=$(echo ${listeRsync} | cut -d- -f2 | cut -d_ -f2)
YEAR=$(echo ${listeRsync} | cut -d- -f2 | cut -d_ -f3)

# Si les informations EXIF sont vides, alors on met dans le dossier ATRIER
if [ "$DAY" = "" ] && [ "$MONTH" = "" ] && [ "$YEAR" = "" ]; then
	DSTDIR="${PHOTOS_ROOT}/ATRIER"
else
	DSTDIR="${PHOTOS_ROOT}/${YEAR}/${MONTH}/${YEAR}-${MONTH}-${DAY}_"
fi
mkdir -p "$DSTDIR"
rsync --no-relative --files-from="${TMPDIR}/${listeRsync}" -avP . $DSTDIR
done

#onEnd

Rapidement :

Il récupère les fichiers *.jpg dans un repertoire source a coup de find. Il execute un exif sur chaque fichier pour recuperer les dates. Ensuite, il créé un fichier liste pour chaque jour. Et enfin, pour chaque liste, il envoie la liste a rsync au bon repertoire (genre : photos/2006/10/2006-10-24_ )

Apres, suffit juste de rajouter un nom a la fin du repertoire, car mon script n'arrive pas encore a determiner si la photo a été pris a un mariage ou a un concert de sadistic music.

Bref, y'a encore des choses a améliorer :

* le lancer a chaque fois que mon téléphone portable est detecté par bluetooth pour synchroniser tout ca

* detecter si d'autres repertoires nommés : photos/2006/10/2006-10-24_* existe, auquel cas, faire la liste des fichiers et comparer au contenu du téléphone, pour par recréer un repertoire photos/2006/10/2006-10-24_ qui contiendra des doublons avec photos/2006/10/2006-10-24_SadisticMusic et photos/2006/10/2006-10-24_MariageSM

Link to comment
Share on other sites

Joli travail :francais:

le code est propre, c'est commenté ! et utile :)

prochaine étape : le réécrire en 10 lignes de PERL :francais: ?? :chinois:

Merci pour mon code, car moi je ne considère pas comme tres propre ^^

Autre chose a améliorer :

* conserver le resultat d'exif et traiter ce resultat plutot que la sortie de la commande exif meme. (ca evite de lancer exif 3x sur la meme photo)

Pour la partie perl, je te laisse le soin de le faire... en 10 lignes :smack:

Link to comment
Share on other sites

quand tu fais

# Si les informations EXIF sont vides, alors on met dans le dossier ATRIER
if [ "$DAY" = "" ] && [ "$MONTH" = "" ] && [ "$YEAR" = "" ]; then
	DSTDIR="${PHOTOS_ROOT}/ATRIER"

t'es sur que c'est pas des || que tu veux faire ? Je ne sais pas si c'est possible qu'il n'y ait que la moitié des infos de date, mais si c'est le cas, tu risques des bugs.

prochaine étape, tout réécrire en 1 ligne de brainfuck ;)

Link to comment
Share on other sites

quand tu fais

# Si les informations EXIF sont vides, alors on met dans le dossier ATRIER
if [ "$DAY" = "" ] && [ "$MONTH" = "" ] && [ "$YEAR" = "" ]; then
	DSTDIR="${PHOTOS_ROOT}/ATRIER"

t'es sur que c'est pas des || que tu veux faire ? Je ne sais pas si c'est possible qu'il n'y ait que la moitié des infos de date, mais si c'est le cas, tu risques des bugs.

prochaine étape, tout réécrire en 1 ligne de brainfuck :francais:

lol brainfuck \o/

Bah c possible, mais ca fout moins la merde qu'un EXIF tout vide. Faudrait revoir ca de toute facon.

Par contre, je faisais deja la récupération de l'EXIF tout court puis utilisation 3x de suite... Donc mon TODO du dessus n'est pas tres juste... Qu'est ce que je suis bien quand meme... J'y avais pensé et deja reglé le probleme ! :roll:

Link to comment
Share on other sites

Vous vouliez quelque chose en perl? :transpi:

Le seul point un peu chiant, c'est qu'il faut Image::ExifTool.

(j'ai utilisé g-cpan sous gentoo pour l'installer)

Après y'a déjà un avantage intéressant par rapport à la version shell : j'ai pas eu à utiliser de dossier/fichiers temporaires : y'a donc que 2 dossiers à prendre en compre : le dossier source contenant les photos et le dossier destination.

Au niveau de la vitesse c'est peut-être mieux (je peux pas dire puisque j'ai pas lancé la version shell...).

#!/usr/bin/perl

# Sort files based on exif date information
#
# Copyright (C) 2007 tuXXX
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Required :
# perl package - Image::ExifTool
# command	  - rsync

use strict;
use warnings;
use File::Find;
use Image::ExifTool;

sub parse_exif_date
{
return $_[0] =~
m/^([0-9]{4}):([0-9]{2}):([0-9]{2}) (([0-9]{2}):([0-9]{2}):([0-9]{2}))$/;
}

sub process_each_file
{
our $tmpdir;
our %files;
my $file = $File::Find::name;
return if not -f $file;
my $datefield = "CreateDate"; #"CreateDate","DateTimeOriginal","ModifyDate"
my $info = Image::ExifTool::ImageInfo($file, $datefield);
my $date = $$info{$datefield};
if(my ($year, $month, $day, $hour) = parse_exif_date($date))
{
	my $key = "$year-$month-$day";
	push(@{$files{$key}}, $file);
}
else
{
	my $key = "sort";
	push(@{$files{$key}}, $file);
}
}

# Usage : $0 directory_to_check tmpdir_base
if($#ARGV<1)
{
print STDERR "Usage: $0 src_root dst_root\n";
exit 1;
}

my $src_root=$ARGV[0];
my $dst_root=$ARGV[1];

die "$dst_root doesn't exist!" unless -d $dst_root;

our %files;
find(\&process_each_file, $src_root);

for my $date (keys %files)
{
print "$date\n";
my $dstdir="$dst_root/$date/";
system("rsync","-avP",@{$files{$date}},"$dstdir");
}

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...