Subversion Repositories eFlore/Applications.cel

Compare Revisions

Ignore whitespace Rev 1188 → Rev 1189

/trunk/jrest/services/MigrationImages.php
1,30 → 1,30
<?php
 
class MigrationImages extends Cel {
 
public static $bdd_cel_migration;
public static $bdd_utilisateurs;
 
const truncate = true; //Doit on vider les tables de destination ?
 
const separateur_champs_metadonnees = ';';
const separateur_valeurs_metadonnees = ':';
 
private $id_cle_metadonnees = array();
 
/** Tableau associatif permettant de stocker l'avancement dans une boucle.
* La clé est un md5 du message à afficher au démarrage de la boucle.
* @var array
*/
private static $avancement = array();
 
const dry_run = false;
 
private $tableau_utilisateurs = array();
private $tableau_observations = array();
private $tableau_mots_cles = array();
private $tableau_nouveau_ancien = array(
 
private $tableau_nouveau_ancien = array(
'id_image' => 'ci_id_image',
'ordre' =>'ci_ordre',
'ce_utilisateur' => 'traiterIdentifiantUtilisateur',
48,7 → 48,7
'date_modification' => 'ci_meta_date',
'date_creation' => 'ci_meta_date_ajout'
);
 
private $champs_exifs_non_gardes = array(
'ci_meta_x_resolution',
'ci_meta_y_resolution',
85,7 → 85,7
'ci_meta_exif_sharpness',
'ci_meta_exif_subject_distance_range'
);
 
private $champs_iptc_non_gardes = array(
'ci_meta_iptc_category',
'ci_meta_iptc_by_line',
100,12 → 100,12
'ci_meta_iptc_copyright_notice',
'ci_meta_iptc_contact'
);
 
private $champs_divers_non_gardes = array(
'ci_publiable_eflore',
'ci_meta_mots_cles'
);
 
/**
* Utiliser cette méthode dans une boucle pour afficher un message suivi du nombre de tour de boucle effectué.
* Vous devrez vous même gérer le retour à la ligne à la sortie de la boucle.
118,41 → 118,41
if (! isset(self::$avancement[$message])) {
self::$avancement[$message] = $depart;
echo "$message : ";
 
$actuel =& self::$avancement[$message];
echo $actuel++;
} else {
$actuel =& self::$avancement[$message];
 
// Cas du passage de 99 (= 2 caractères) à 100 (= 3 caractères)
$passage = 0;
if (strlen((string) ($actuel - 1)) < strlen((string) ($actuel))) {
$passage = 1;
}
 
echo str_repeat(chr(8), (strlen((string) $actuel) - $passage));
echo $actuel++;
}
}
 
/**
* Méthode appelée avec une requête de type GET.
*/
public function getElement($params) {
 
if(!isset($this->config['database_cel']['database_migration']) || $this->config['database_cel']['database_migration'] == '') {
echo 'Attention la variable de configuration database_migration dans la section database_cel, contenant la base de données d\'arrivée, doit être remplie '."\n";
exit;
}
 
if(!isset($this->config['database_ident']['database']) || $this->config['database_ident']['database'] == '') {
echo 'Attention la variable de configuration database dans la section database_ident, contenant la base de données utilisateurs, doit être remplie '."\n";
exit;
}
 
self::$bdd_cel_migration = $this->config['database_cel']['database_migration'];
self::$bdd_utilisateurs = $this->config['database_ident']['database'];
 
$this->id_cle_metadonnees = array_merge($this->tableau_ids_tags_exif, $this->tableau_ids_tags_iptc);
 
echo "--MIGRATION DES IMAGES --------------------------------------\n";
161,7 → 161,7
echo "-------------------------------------------------------------------\n\n";
echo " ETAPE 0. Vider les tables ... \n\n";
echo "-------------------------------------------------------------------\n\n";
$nouvellesTables = array('`cel_images`', '`cel_obs_images`');
$nouvellesTables = array('cel_images', 'cel_obs_images');
foreach ($nouvellesTables as $nomTable) {
echo 'Vider la table '.$nomTable.'...';
$requeteTruncate = 'TRUNCATE TABLE '.self::$bdd_cel_migration.'.'.$nomTable;
168,10 → 168,10
$resultatTruncate = $this->executerRequete($requeteTruncate);
echo "ok \n";
}
 
echo "\n---------------------------------------------------------------- OK\n\n";
}
 
echo "-------------------------------------------------------------------\n\n";
echo " ETAPE 1. Paramétrage ... \n\n";
echo "-------------------------------------------------------------------\n\n";
178,13 → 178,13
$this->getUtilisateurs();
$this->getMotsCles();
$this->getObservations();
 
echo "-------------------------------------------------------------------\n\n";
echo " ETAPE 2. Migration des images ... \n\n";
echo "-------------------------------------------------------------------\n\n";
$this->migrerImages();
echo "\n"."\n"."\n";
 
echo "-------------------------------------------------------------------\n\n";
echo " ETAPE 3. migration des liaisons obs images ... \n\n";
echo "-------------------------------------------------------------------\n\n";
191,26 → 191,26
$this->migrerLiaisonsObsImages();
echo "\n"."\n"."\n";
}
 
private function getUtilisateurs() {
echo "\n-------------------------------------------------------------------\n";
echo "--SELECTION DES UTILISATEURS---------------------------------------\n\n";
 
$requete_selection_utilisateurs = 'SELECT U_ID as id, U_MAIL as mail, U_NAME as nom, U_SURNAME as prenom, U_PASSWD as pass FROM '.self::$bdd_utilisateurs.'.annuaire_tela';
$tableau_utilisateurs = $this->executerRequete($requete_selection_utilisateurs);
 
foreach( $tableau_utilisateurs as &$utilisateur) {
$this->tableau_utilisateurs[$utilisateur['mail']] = $utilisateur;
}
 
echo sizeof($this->tableau_utilisateurs)." utilisateurs sélectionnés";
echo "\n-----------------------------------------------------------------OK\n";
}
 
private function getMotsCles() {
echo "\n-------------------------------------------------------------------\n";
echo "--SELECTION DES MOTS-CLES -----------------------------------------\n\n";
 
$requete_selection_mots_cles = 'SELECT cmc_id_proprietaire as id_utilisateur, cmc_id_mot_cle_utilisateur as id_mot_cle, cmc_mot_cle as mot_cle FROM cel_mots_cles_obs';
$tableau_mots_cles = $this->executerRequete($requete_selection_mots_cles);
 
217,20 → 217,20
foreach( $tableau_mots_cles as &$mot_cle) {
$this->tableau_mots_cles[$mot_cle['id_utilisateur']][$mot_cle['id_mot_cle']] = $mot_cle;
}
 
echo sizeof($this->tableau_mots_cles)." mots-clés sélectionnés";
echo "\n-----------------------------------------------------------------OK\n";
 
}
 
private function getObservations() {
 
$pas = 5000;
 
$nObs = "SELECT COUNT(*) AS nb FROM cel_inventory";
$resultatNbObs = $this->executerRequete($nObs);
$nbObs = $resultatNbObs[0]['nb'];
 
for ($i = 0; $i < 230000; $i += $pas ) {
$requete_selection_observations = 'SELECT id, ordre, identifiant FROM cel_inventory LIMIT '.$i.", $pas";
$tableau_observations = $this->executerRequete($requete_selection_observations);
237,70 → 237,70
foreach($tableau_observations as &$obs) {
$this->tableau_observations[$obs['identifiant']][$obs['ordre']] = $obs['id'];
}
 
$this->afficherAvancement('Selection des observations (par '.$pas.' )', $nbObs);
}
 
echo "\n\n";
}
 
public function executerRequeteSimple($requete) {
// Fonction de commodité pour afficher les requetes au lieu de les executer
if (self::dry_run) {
echo str_replace('),','),'."\n", $requete)."\n";
echo str_replace('),','),'."\n", $requete)."\n";
return true;
} else {
return parent::executerRequeteSimple($requete);
}
}
 
private function migrerImages() {
 
$debut = 0;
$pas = 200;
$fin = 150000;
$pas = 200;
$fin = 150000;
 
//Selectionner le nombre d'images
$requeteNbImg = "SELECT COUNT(*) as nb FROM cel_images";
$resultatNbImg = $this->executerRequete($requeteNbImg);
$fin = $resultatNbImg[0]['nb'];
 
for ($i = $debut; $i <= $fin ; $i += $pas) {
$requete_selection_images = 'SELECT * FROM cel_images '.
'ORDER BY ci_id_image ASC LIMIT '.$i.','.$pas;
$images = @$this->requeter($requete_selection_images);
 
$images = @$this->requeter($requete_selection_images);
 
$requete_insertion_images = 'INSERT INTO '.self::$bdd_cel_migration.'.cel_images (';
foreach ($this->tableau_nouveau_ancien as $nouveau_champ => $ancien_champ) {
$requete_insertion_images .= $nouveau_champ.',';
}
}
$requete_insertion_images = rtrim($requete_insertion_images, ',');
 
$requete_insertion_images = $requete_insertion_images.') VALUES ';
if (is_array($images)) {
 
if (is_array($images)) {
 
$nb_images_a_traiter = count($images);
 
foreach($images as $image) {
 
$nouvelle_image = $this->traiterLigneImage($image);
 
$nouvelle_image = array_map(array($this,'proteger'),$nouvelle_image);
$requete_insertion_images .= '('.join(',',array_values($nouvelle_image)).'),';
}
 
$requete_insertion_images = rtrim($requete_insertion_images, ',');
$migration_images = $this->executer($requete_insertion_images);
 
if (!$migration_images) {
echo 'la migration des images '.$i.' à '.($i+$nb_images_a_traiter).' a échoué '."\n";
} else {
$this->afficherAvancement('Migration des images (par '.$pas.' )', $fin);
}
}
}
 
if(count($images) < $pas) {
echo "\n---------------------------------------------------------------- OK\n\n";
return;
307,45 → 307,45
}
}
}
 
private function migrerLiaisonsObsImages() {
$debut = 0;
$pas = 500;
$fin = 50000;
$pas = 500;
$fin = 50000;
 
$liaisons_obs_inexistantes = 0;
 
//Selectionner le nombre de liaisons
$requeteNbImgObs = "SELECT COUNT(*) as nb FROM cel_obs_images";
$resultatNbImgObs = $this->executerRequete($requeteNbImgObs);
$fin = $resultatNbImgObs[0]['nb'];
 
for ($i = $debut; $i <= $fin ; $i += $pas) {
 
if($i > $fin) {
$i = $fin;
}
 
$requete_selection_liaisons = 'SELECT * FROM cel_obs_images LIMIT '.$i.','.$pas;
$tableau_liaisons = $this->executerRequete($requete_selection_liaisons);
 
$requete_migration_liaison = 'INSERT INTO '.self::$bdd_cel_migration.'.cel_obs_images '.
'(id_image, id_utilisateur, id_observation, date_liaison) '.
'VALUES ';
 
$sous_requete_insertion = '';
 
if(is_array($tableau_liaisons)) {
foreach($tableau_liaisons as &$liaison) {
 
$mail_utilisateur = $liaison['coi_ce_utilisateur'];
$utilisateur = $this->renvoyerIdPourMigration($mail_utilisateur);
 
$id_obs = $liaison['coi_ce_observation'];
 
if (isset($this->tableau_observations[$mail_utilisateur][$id_obs])) {
$id_obs = $this->tableau_observations[$mail_utilisateur][$id_obs];
 
$sous_requete_insertion .= '('.$this->proteger($liaison['coi_ce_image']).','.
$this->proteger($utilisateur).','.
$this->proteger($id_obs).','.
356,17 → 356,17
$liaisons_obs_inexistantes++;
}
}
 
$sous_requete_insertion = rtrim($sous_requete_insertion,',');
$requete_migration_liaison = $requete_migration_liaison.$sous_requete_insertion;
 
$migration_liaison = $this->executerRequeteSimple($requete_migration_liaison);
 
if (!$migration_liaison) {
echo 'la migration des liaisons obs images de '.$i.' à '.($i+$pas).' a échoué ! '."\n<br />";
} else {
$this->afficherAvancement('Migration des liaisons obs images (par '.$pas.' )', $fin);
}
}
}
}
echo "\n\n";
374,13 → 374,13
echo "\n";
echo "\n---------------------------------------------------------------- OK\n\n";
}
 
private function traiterLigneImage($image) {
 
$nouvelle_image = array();
foreach ($this->tableau_nouveau_ancien as $nouveau_champ_image => $ancien_champ_image) {
 
foreach ($this->tableau_nouveau_ancien as $nouveau_champ_image => $ancien_champ_image) {
 
if ($this->estUnChampATraiter($ancien_champ_image)) {
if (method_exists($this,$ancien_champ_image)) {
$nouvelle_image[$nouveau_champ_image] = $this->$ancien_champ_image($image);
393,54 → 393,54
$nouvelle_image[$nouveau_champ_image] = $image[$ancien_champ_image];
}
}
 
return $nouvelle_image;
}
 
private function estUnChampATraiter($champ) {
 
return strpos($champ, 'traiter') !== false;
}
 
private function traiterMotsClesTexte($ligne_image) {
 
$mail_image = $ligne_image['ci_ce_utilisateur'];
$retour = $ligne_image['ci_meta_mots_cles'];
 
if (isset($this->tableau_mots_cles[$mail_image])) {
 
$mots_cles_tableau = $this->parserMotsCles($mail_image, $ligne_image['ci_meta_mots_cles'], ',');
$retour = join(';',$mots_cles_tableau);
$retour = ltrim($retour,';;') ;
}
 
return $retour;
}
}
 
private function parserMotsCles($utilisateur, $mot_cles, $separateur = ',') {
 
$tableau_mots_cles = explode($separateur,$mot_cles);
$tableau_mots_cles_formates = array();
 
foreach($tableau_mots_cles as $mot_cle) {
 
$mot_cle = str_replace($separateur.$separateur,'',$mot_cle);
$mot_cle = str_replace('null','',$mot_cle);
 
if ($this->estUnIdentifiantMotCle($mot_cle)) {
 
// certains mots clés mal formatés contiennent des virgules
if (strpos($mot_cle,',') !== false) {
$tab_mot_cle_mal_formate = explode(',',$mot_cle);
 
foreach ($tab_mot_cle_mal_formate as $mot_cle_mal_formate) {
if ($this->estUnIdentifiantMotCle($mot_cle_mal_formate)) {
$tableau_mots_cles_formates[$mot_cle_mal_formate] = $this->tableau_mots_cles[$utilisateur][$mot_cle_mal_formate]['mot_cle'];
}
}
}
} else {
// on met le mot clé dans sa propre case afin d'éviter
// facilement les doublons provoqués par de mauvais formatages
// facilement les doublons provoqués par de mauvais formatages
if(isset($this->tableau_mots_cles[$utilisateur][$mot_cle])) {
$tableau_mots_cles_formates[$mot_cle] = $this->tableau_mots_cles[$utilisateur][$mot_cle]['mot_cle'];
}
448,58 → 448,58
 
}
}
 
return $tableau_mots_cles_formates;
}
 
private function estUnIdentifiantMotCle($chaine) {
return trim($chaine) != '' && preg_match('/[0-9A-Z]+\.[0-9A-Z]+/i', $chaine) ;
}
 
private function traiterIdentifiantUtilisateur($ligne_image) {
 
$mail_image = $ligne_image['ci_ce_utilisateur'];
$retour = $this->renvoyerIdPourMigration($mail_image);
 
return $retour;
}
 
private function traiterPrenomUtilisateur($ligne_image) {
 
$mail_image = $ligne_image['ci_ce_utilisateur'];
$retour = $mail_image;
 
if (isset($this->tableau_utilisateurs[$mail_image])) {
$retour = $this->tableau_utilisateurs[$mail_image]['prenom'];
} else {
$retour = '';
}
 
return $retour;
}
 
private function traiterNomUtilisateur($ligne_image) {
 
$mail_image = $ligne_image['ci_ce_utilisateur'];
$retour = $mail_image;
 
if (isset($this->tableau_utilisateurs[$mail_image])) {
$retour = $this->tableau_utilisateurs[$mail_image]['nom'];
} else {
$retour = '';
}
 
return $retour;
}
 
private function decoderTableauMetaDonnees($chaine) {
 
$tableau_valeurs_decodees = array();
 
if (trim($chaine) != '') {
if (trim($chaine) != '') {
$tableau_meta = explode(self::separateur_champs_metadonnees,$chaine);
foreach ($tableau_meta as &$chaine_meta) {
 
$cle_valeur = explode(self::separateur_valeurs_metadonnees, $chaine_meta);
if (is_array($cle_valeur) && count($cle_valeur) == 2) {
$cle = ltrim($cle_valeur[0],' ');
507,14 → 507,14
}
}
}
 
return $tableau_valeurs_decodees;
}
 
private function convertirTableauMetadonneesEnXml($tableau) {
 
$xml = '';
 
foreach($tableau as $cle => $valeur) {
 
$cle = str_replace('ci_meta_exif_','',$cle);
526,35 → 526,35
$id = isset($this->id_cle_metadonnees[$cle]) ? $this->id_cle_metadonnees[$cle] : $cle;
$xml .= '<'.$cle.' id="'.$id.'">'.$valeur.'</'.$cle.'>'."\n";
}
 
return $xml;
}
 
private function peutUtiliserExifTool() {
return file_exists('/usr/bin/exiftool') && is_executable('/usr/bin/exiftool');
}
 
private function decoderMetadonnees($chemin_image) {
 
$res = '';
 
if($this->peutUtiliserExifTool()) {
$res = $this->decoderMetadonneesExifTool($chemin_image);
 
$xml_meta = '<?xml version="1.0" encoding="UTF-8" ?>';
$xml_meta .= '<exif>';
 
foreach($res['EXIF'] as $prop => $valeur) {
$xml_meta .= ' <'.$prop.' id="'.$valeur['id'].'">'.$valeur['valeur'].'</'.$prop.'>'."\n";
}
$xml_meta .= '</exif>'."\n";
 
$xml_meta .= '<iptc>';
foreach($res['IPTC'] as $prop => $valeur) {
$xml_meta .= ' <'.$prop.' id="'.$valeur['id'].'">'.$valeur['valeur'].'</'.$prop.'>'."\n";
}
$xml_meta .= '</iptc>'."\n";
 
$xml_meta .= '<xmp>';
foreach($res['XMP'] as $prop => $valeur) {
$xml_meta .= ' <'.$prop.' id="'.$valeur['id'].'">'.$valeur['valeur'].'</'.$prop.'>'."\n";
561,18 → 561,18
}
$xml_meta .= '</xmp>'."\n";
} else {
 
}
 
return $xml_meta;
}
 
private function decoderMetadonneesExifTool($chemin_image) {
$metadata = array();
$res = exec('/usr/bin/exiftool -g -D '.$chemin_image, $metadata);
$res = exec('/usr/bin/exiftool -g -D '.$chemin_image, $metadata);
 
$metadata_decodees = array();
 
$categorie = '';
foreach($metadata as &$data) {
if($this->estUnSeparateurCategorieExifTool($data)) {
584,58 → 584,58
$this->id_cle_metadonnees[$cle_metadonnee] = $data_decodee['id'];
}
}
 
return $metadata_decodees;
}
 
private function estUnSeparateurCategorieExifTool($data) {
return preg_match('^---- (.)* ----^',$data);
return preg_match('^---- (.)* ----^',$data);
}
 
private function parserValeurMetadonneeExifTool($data) {
$cle_valeur = explode(':',$data);
 
$valeur = '';
if(count($cle_valeur) == 2) {
$valeur = trim($cle_valeur[1]);
}
 
$id_cle = explode(' ',trim($cle_valeur[0]),2);
 
$id_cle[1] = str_replace(array('-','/'),'',$id_cle[1]);
 
$cle_id_valeur = array('cle' => $id_cle[1], 'id' => str_replace('-','',$id_cle[0]), 'valeur' => $valeur);
return $cle_id_valeur;
return $cle_id_valeur;
}
 
private function traiterExif($ligne_image) {
 
$metadonnees_autres = $this->decoderTableauMetaDonnees($ligne_image['ci_meta_exif_autres']);
$metadonnees = array_intersect_key($ligne_image, array_flip($this->champs_exifs_non_gardes))+$metadonnees_autres;
 
$xml_meta = '<?xml version="1.0" encoding="UTF-8" ?>';
$xml_meta .= '<exif>';
$xml_meta .= $this->convertirTableauMetadonneesEnXml($metadonnees);
$xml_meta .= '</exif>';
 
return $xml_meta;
}
 
private function traiterIptc($ligne_image) {
 
$metadonnees_autres = $this->decoderTableauMetaDonnees($ligne_image['ci_meta_iptc_autres']);
$metadonnees = array_intersect_key($ligne_image, array_flip($this->champs_iptc_non_gardes))+$metadonnees_autres;
 
$xml_meta = '<?xml version="1.0" encoding="UTF-8" ?>';
$xml_meta .= '<iptc>';
$xml_meta .= $this->convertirTableauMetadonneesEnXml($metadonnees);
$xml_meta .= '</iptc>';
 
return $xml_meta;
}
 
private function traiterXmp($ligne_image) {
 
$chemin = $this->obtenirCheminImageOriginale($ligne_image['ci_id_image']);
// TODO décommenté car pour le moment ça n'est pas necessaire, à éxécuter à part
//$res = $this->decoderMetadonneesExifTool($chemin);
647,12 → 647,12
}
}
$xml .= '</xmp>';
 
return $xml;
}
 
private function traiterMakernote($ligne_image) {
 
$chemin = $this->obtenirCheminImageOriginale($ligne_image['ci_id_image']);
//$res = $this->decoderMetadonneesExifTool($chemin);
$xml = '<?xml version="1.0" encoding="UTF-8" ?>';
663,42 → 663,42
}
}
$xml .= '</makernote>';
 
return '';
}
 
public function obtenirCheminImageOriginale($id_image) {
$nom = $this->convertirIdBddVersNomFichier($id_image, 'O');
$dossier = $this->obtenirDossierPourFormat($id_image,'O');
 
return $dossier.'/'.$nom;
}
 
public function convertirIdBddVersNomFichier($id, $format, $extension = 'jpg') {
// creation du format original
$id_avec_zeros = sprintf('%09s', $id) ;
$id_avec_zeros_underscores = wordwrap($id_avec_zeros, 3 , '_', true) ;
 
$nom_fichier = $id_avec_zeros_underscores.'_'.$format.'.'.$extension;
 
return $nom_fichier;
}
 
public function obtenirDossierPourFormat($id, $format) {
$chemin_base = $this->config['cel']['chemin_images'];
 
$chemin_sur_serveur = $chemin_base;
 
$id = sprintf('%09s', $id);
$id = wordwrap($id, 3 , '_', true);
 
list($dossierNiveau1, $dossierNiveau2) = explode('_', $id);
 
$chemin_sur_serveur_final = $chemin_sur_serveur.'/'.$dossierNiveau1.'/'.$dossierNiveau2.'/'.$format;
 
return $chemin_sur_serveur_final;
}
 
private function renvoyerIdPourMigration($utilisateur) {
// si tout les test suivant échouent, on garde l'utilisateur tel quel
// (cas de la chaine de session des utilisateur anonymes)
713,15 → 713,15
$retour = md5($utilisateur);
}
}
 
return $retour;
}
 
public function mailValide($mail) {
// vérification bidon mais ça suffit pour ici
return !(strpos('@',$mail) === false);
return !(strpos('@',$mail) === false);
}
 
private $tableau_ids_tags_exif = array('InteropIndex' => '1',
'InteropVersion' => '2',
'ProcessingSoftware' => '11',
1137,7 → 1137,7
'Smoothness' => '65111',
'MoireFilter' => '65112',
);
 
private $tableau_ids_tags_iptc = array('ApplicationRecordVersion' => '0',
'ObjectTypeReference' => '3',
'ObjectAttributeReference' => '4',