16ar Posté(e) le 18 mars 2007 Partager Posté(e) le 18 mars 2007 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 Lien vers le commentaire Partager sur d’autres sites More sharing options...
Sandeman Posté(e) le 20 mars 2007 Partager Posté(e) le 20 mars 2007 Joli travail le code est propre, c'est commenté ! et utile :) prochaine étape : le réécrire en 10 lignes de PERL ?? Lien vers le commentaire Partager sur d’autres sites More sharing options...
16ar Posté(e) le 20 mars 2007 Auteur Partager Posté(e) le 20 mars 2007 Joli travail le code est propre, c'est commenté ! et utile :) prochaine étape : le réécrire en 10 lignes de PERL ?? 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 Lien vers le commentaire Partager sur d’autres sites More sharing options...
lorinc Posté(e) le 21 mars 2007 Partager Posté(e) le 21 mars 2007 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 Lien vers le commentaire Partager sur d’autres sites More sharing options...
16ar Posté(e) le 21 mars 2007 Auteur Partager Posté(e) le 21 mars 2007 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 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 ! Lien vers le commentaire Partager sur d’autres sites More sharing options...
tuXXX Posté(e) le 21 mars 2007 Partager Posté(e) le 21 mars 2007 Vous vouliez quelque chose en perl? 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"); } Lien vers le commentaire Partager sur d’autres sites More sharing options...
Messages recommandés
Archivé
Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.