•  » Plugins
  •  » [Résolu] AMetaData 0.5.2 bug ?

#1 2010-10-08 08:41:36

philihp
Membre
2010-10-08
19

[Résolu] AMetaData 0.5.2 bug ?

Bonjour,

j'utilise Piwigo 2.1.3 avec PHP: 5.2.6-1 et mysql: 5.0.51a-24 sur serveur Apache2 (Distribution Debian Lenny)  je rencontre le problème suivant :

j'ai tagué mes photos avec Digikam (plusieurs keywords par photo) et lors de l'utilisation du plugin AMetaData (version 0.5.2) avec l'onglet Tag l'extraction des mots clés est partielle et le nombre de photos correspondant à un mot clé extrait est inexact : est-ce une mauvaise manip de ma part ?

Ce plugin est Kolossal.

Merci à son créateur et développeur.

Hors ligne

#2 2010-10-08 11:43:11

grum
Équipe Piwigo
50% Nantes - 50% Paris
2007-09-10
2502

Re: [Résolu] AMetaData 0.5.2 bug ?

Peux-tu être plus précis dans la description du problème ?

digiKam permet de gérer les tags de façon hiérachique, par exemple :
Nourriture
  Fruit
    Pomme
      Granny Smith
 

digiKam enregistre ses tags dans une métadonnée XMP spécifique à digiKam (la métadonnée <digiKam:TagsList>) sous le format "Nourriture / Fruit / Pomme / Granny Smith"

Lors de l'implémentation de de la fonctionnalité, je me suis retrouvé face au problème suivant : Piwigo ne gèrant pas l'arborescence de tags, comment intégrer cette hiérarchie ?

J'avais deux solutions :
- intégrer chaque élément de la hiérarchie
- intégrer le dernier élément de la hiérarchie

Pour diverses raisons, j'ai opté pour la seconde solution.
Pour la prochaine version du plugin, il y a aura une option ou un système quelconque (pas encore réfléchi à la question sur comment çà sera implémenté) permettant à l'utilisateur de choisir le comportement du plugin face à ce type de cas.


Si le problème rencontré n'est pas lié à la hiérarchie des tags, peux-tu m'envoyer une photo ou me donner un lien, et m'expliquer quels sont les tags qui ne sont pas pris en compte ?


Pour le nombre de photos correspondant à un mot clef, il faut bien avoir à l'esprit que s'il existe un tag piwigo "Granny Smith" et que ce dernier est déjà affecté à une photo, si celle-ci dispose du tag "Granny Smith" dans ses métadonnées elle n'est pas comptée.


Mes photos avec Piwigo évidemment !
[ www.grum.fr ] [ photos.grum.fr ]

Hors ligne

#3 2010-10-08 13:33:07

philihp
Membre
2010-10-08
19

Re: [Résolu] AMetaData 0.5.2 bug ?

Bonjour Grum !

Merci pour ta réponse ultra-rapide ! Effectivement il s'agit bien d'un problème de hiérarchie et donc AMetaData fonctionne tout à fait bien chez moi dans sa version actuelle.

Pour résoudre mon problème il faut que je trouve un soft qui tag "à plat" (si quelqu'un a une suggestion ...) peut être une option de configuration dans Digikam ? (je n'y crois guère).

Pour moi ce qui m'arrangerait (là je la joue perso) c'est que AMetaData retienne tous les tags sans tenir compte de la hiérarchie qui m'est utile au moment du taguage dans Digikam mais pas du tout dans PWG. Bref j'aimerais bien retrouver chacun de mes tags individuellement et pouvoir éliminer dans PWG ceux qui sont de trop.

Un petit patch de derrière les fagots Grum ?

Merci

Hors ligne

#4 2010-10-08 14:11:41

grum
Équipe Piwigo
50% Nantes - 50% Paris
2007-09-10
2502

Re: [Résolu] AMetaData 0.5.2 bug ?

A la réflexion, en zieutant le code, j'ai choisit une troisième solution encore plus simple : à priori je récupère tout bêtement la hiérarchie complète "Nourriture / Fruit / Pomme / Granny Smith"


Pour importer "à plat" la hiérachie de tags digiKam, il faut que tu ailles modifier le fichier amd_ajax.php

Entre les lignes 1496 et 1679, tu trouves deux fonctions ajax_amd_admin_tagsGetKeywords() et ajax_amd_admin_tagsConvertKeywords()

Tu remplaces le code de celles-ci par le code ci-dessous :

Code:

    /**
     * return an html list of found keywords in the images_tags table
     *
     * @return String : html formatted list
     */
    private function ajax_amd_admin_tagsGetKeywords()
    {
      global $template;

      $returned=array();
      $keywordsList=array();
      $sql="SELECT pait.value, pait.imageId, paut.numId, paut.tagId
            FROM (".$this->tables['images_tags']." pait
              JOIN ".$this->tables['used_tags']." paut ON pait.numId = paut.numId)

            WHERE (paut.tagId = 'xmp.dc:subject' OR
                   paut.tagId = 'xmp.digiKam:TagsList' OR
                   paut.tagId = 'iptc.Keywords');";
      $result=pwg_query($sql);
      if($result)
      {
        while($row=pwg_db_fetch_assoc($result))
        {
          if(preg_match('/^a:\d+:{/', $row['value']))
          {
            /*
             *  if value is a serialized string, unserialize and process it
             */
            $tmp=unserialize($row['value']);
            foreach($tmp['values'] as $val)
            {
              if($row['tagId']=='xmp.digiKam:TagsList')
              {
                $list=explode('/', $val);
                foreach($list as $subTag)
                {
                  $keywordsList[]="('".mysql_escape_string(trim($subTag))."', ".$row['imageId'].")";
                }
              }
              else
              {
                $keywordsList[]="('".mysql_escape_string($val)."', ".$row['imageId'].")";
              }
            }
          }
          else
          {
            $keywordsList[]="('".mysql_escape_string($row['value'])."', ".$row['imageId'].")";
          }
        }

        if(count($keywordsList)>0)
        {
          $sql="CREATE TEMPORARY TABLE amd_temp_tags (
                  `value` CHAR(255) default '',
                  `imageId` mediumint(8) unsigned NOT NULL default '0',
                  PRIMARY KEY  USING BTREE (`value`,`imageId`)
                ) CHARACTER SET utf8 COLLATE utf8_general_ci;";
          if(pwg_query($sql))
          {
            $sql="INSERT IGNORE INTO amd_temp_tags
              VALUES ".implode(',', $keywordsList);
            if(pwg_query($sql))
            {
              $sql="SELECT att.value AS value,
                      COUNT(DISTINCT att.imageId) AS nbPictures,
                      IF(ptt.name IS NULL, 'n', 'y') AS tagExists,
                      COUNT(DISTINCT pit.image_id) AS nbPicturesTagged
                    FROM (amd_temp_tags att LEFT JOIN ".TAGS_TABLE."  ptt ON att.value = ptt.name)
                      LEFT JOIN ".IMAGE_TAG_TABLE." pit ON pit.tag_id = ptt.id
                    GROUP BY att.value
                    HAVING nbPicturesTagged < nbPictures";
              $result=pwg_query($sql);
              if($result)
              {
                $i=0;
                while($row=pwg_db_fetch_assoc($result))
                {
                  $row['id']=$i;
                  $returned[]=$row;
                  $i++;
                }
              }
            }
          }
        }
      }

      $template->set_filename('keywordsList',
                    dirname($this->getFileLocation()).'/admin/amd_metadata_tags_iKeywordsList.tpl');

      $template->assign('datas', $returned);
      return($template->parse('keywordsList', true));
    }


    /**
     * convert given keywords into tags, and associate them to pictures
     *
     * @param Array $keywords : an array of strings
     * @return String : ok or ko
     */
    private function ajax_amd_admin_tagsConvertKeywords($keywords)
    {
      global $template;

      $returned='ko';

      /*
       * 1/ build a temp table with all couple of keywords/imageId
       */
      $keywordsList=array();
      $sql="SELECT pait.value, pait.imageId, paut.numId, paut.tagId
            FROM (".$this->tables['images_tags']." pait
              JOIN ".$this->tables['used_tags']." paut ON pait.numId = paut.numId)

            WHERE (paut.tagId = 'xmp.dc:subject' OR
                   paut.tagId = 'xmp.digiKam:TagsList' OR
                   paut.tagId = 'iptc.Keywords');";
      $result=pwg_query($sql);
      if($result)
      {
        while($row=pwg_db_fetch_assoc($result))
        {
          if(preg_match('/^a:\d+:{/', $row['value']))
          {
            /*
             *  if value is a serialized string, unserialize and process it
             */
            $tmp=unserialize($row['value']);
            foreach($tmp['values'] as $val)
            {
              if($row['tagId']=='xmp.digiKam:TagsList')
              {
                $list=explode('/', $val);
                foreach($list as $subTag)
                {
                  $keywordsList[]="('".mysql_escape_string(trim($subTag))."', ".$row['imageId'].")";
                }
              }
              else
              {
                $keywordsList[]="('".mysql_escape_string($val)."', ".$row['imageId'].")";
              }
            }
          }
          else
          {
            $keywordsList[]="('".mysql_escape_string($row['value'])."', ".$row['imageId'].")";
          }
        }
        $sql="CREATE TEMPORARY TABLE amd_temp_tags (
                `value` CHAR(255) default '',
                `imageId` mediumint(8) unsigned NOT NULL default '0',
                PRIMARY KEY  USING BTREE (`value`,`imageId`)
              ) CHARACTER SET utf8 COLLATE utf8_general_ci;";
        if(pwg_query($sql))
        {
          $sql="INSERT IGNORE INTO amd_temp_tags
            VALUES ".implode(',', $keywordsList);
          if(pwg_query($sql))
          {
            foreach($keywords as $key => $val)
            {
              $keywords[$key]="(att.value LIKE '".mysql_escape_string($val)."')";
            }
            /*
             * 2/ join temp table with piwigo tags table, found the keywords
             *    that don't have a corresponding keyword
             */
            $sql="SELECT DISTINCT att.value
                  FROM amd_temp_tags att LEFT JOIN ".TAGS_TABLE." ptt ON att.value = ptt.name
                  WHERE ptt.id IS NULL
                    AND".implode(' OR ', $keywords);
            $result=pwg_query($sql);
            if($result)
            {
              $sql=array();
              while($row=pwg_db_fetch_assoc($result))
              {
                $sql[]="('', '".mysql_escape_string($row['value'])."', '".mysql_escape_string(str2url($row['value']))."')";
              }
              if(count($sql)>0)
              {
                $sql="INSERT INTO ".TAGS_TABLE." VALUES ".implode(',', $sql);
                pwg_query($sql);
              }
            }

            /*
             * 3/ join temp table with piwigo tags table, associate piwigo tagId
             *    to the keywords (at this step, all keyword can be associated
             *    with a piwigo tagId)
             */
            $sql="INSERT IGNORE INTO ".IMAGE_TAG_TABLE."
                    SELECT DISTINCT att.imageId, ptt.id
                    FROM amd_temp_tags att LEFT JOIN ".TAGS_TABLE." ptt ON att.value = ptt.name
                    WHERE ".implode(' OR ', $keywords);
            $result=pwg_query($sql);
            $returned='ok';
          }
        }
      }

      return($returned);
    }

ne te plante pas, et au préalable fait une copie du fichier...

et hop, çà doit répondre à ton besoin :-)


Mes photos avec Piwigo évidemment !
[ www.grum.fr ] [ photos.grum.fr ]

Hors ligne

#5 2010-10-08 17:46:35

philihp
Membre
2010-10-08
19

Re: [Résolu] AMetaData 0.5.2 bug ?

Merci Grum pour ce code !

A première vue les tags semblent "sortir" correctement, il me semble qu'il en manque quelques uns mais je vais refaire la manip avec un nouveau lot de photos taguées par Digikam.

Je reviens faire mon compte rendu après.

Hors ligne

#6 2010-10-09 14:14:20

philihp
Membre
2010-10-08
19

Re: [Résolu] AMetaData 0.5.2 bug ?

Je reviens sur le site après plusieurs tests :

1) j'utilise le plugin AMetaData modifié avec le code tel qu'indiqué par Grum ci-dessus, noter que ce plugin est configuré à l'installation en mode avancé
2) je tague des photos avec DigiKam
3) je charge mes photos par FTP dans PWG
4) je fais mes miniatures et synchronise la base de données
5) je vais dans administration/plugin/AMetadata
6) je mets à jour le référentiel avec les images du panier
7) je vais dans l'onglet "tag" et là : ....

le résultat dépend des photos, pour des images récentes prises avec un appareil bien reconnu (Nikon D40) pas de problèmes, tous les mots clés sont extraits sans tenir compte de leur hiérarchie. Pour des photos très anciennes (12 ans)
- prises  à la préhistoire j'en conviens - à l'époque j'utilisais un des premiers numériques Agfa pour grand public, les mots clés ne sont pas tous pris en compte voire pas du tout ...

Je pense donc qu'il s'agit d'un problème intrinsèque aux fichiers jpeg anciens (mode d'enregistrement ?). Ce qui me laisse perplexe c'est que dans DigiKam tous les fichiers jpeg anciens ou récents sont bien reconnus et tagués sans problèmes.

Affaire à suivre.

Hors ligne

#7 2010-10-09 14:32:00

grum
Équipe Piwigo
50% Nantes - 50% Paris
2007-09-10
2502

Re: [Résolu] AMetaData 0.5.2 bug ?

peux-tu me fournir une des images jpeg dont l'analyse des métadonnées pose problème ?


Mes photos avec Piwigo évidemment !
[ www.grum.fr ] [ photos.grum.fr ]

Hors ligne

#8 2010-10-09 18:27:37

philihp
Membre
2010-10-08
19

Re: [Résolu] AMetaData 0.5.2 bug ?

En voici une ici

Hors ligne

#9 2010-10-09 18:48:25

grum
Équipe Piwigo
50% Nantes - 50% Paris
2007-09-10
2502

Re: [Résolu] AMetaData 0.5.2 bug ?

Un fichier Jpeg commence par le SOI (Start Of Image) qui a la valeur 0xFFD8 et finit par le EOI (End Of Image) qui a la valeur 0xFFD9


En l'occurence, ta photo commence bien par le SOI, mais ne finit pas avec le EOI : il y a des données additionnelles situées après (290 octets qui servent à je ne sais pas quoi).
Et le plugin est conçut un peu bêtement : il cherche le EOI à la fin du fichier, et s'il ne le trouve il dit que c'est pas une image Jpeg et donc il ne lit pas les métadonnées.

En levant le contrôle, j'arrive bien à lire les métadonnées.

Donc, en attendant que je fasse un reader plus intelligent (comprendre : capable de chercher le EOI même s'il y a des données additionnelles), tu peux faire la manip suivante :

Dans le répertoire du plugin, modifier le fichier JpegMetadata/Readers/JpegReader.class.php, trouver la ligne 176 :

Code:

if(ConvertData::toUShort($header, BYTE_ORDER_BIG_ENDIAN) == self::JPEG_EOI)

et la mettre en commentaire :

Code:

// if(ConvertData::toUShort($header, BYTE_ORDER_BIG_ENDIAN) == self::JPEG_EOI)

les métadonnées de ta photo seront reconnues...


Mes photos avec Piwigo évidemment !
[ www.grum.fr ] [ photos.grum.fr ]

Hors ligne

#10 2010-10-09 18:57:54

grum
Équipe Piwigo
50% Nantes - 50% Paris
2007-09-10
2502

Hors ligne

#11 2010-10-09 23:22:10

philihp
Membre
2010-10-08
19

Re: [Résolu] AMetaData 0.5.2 bug ?

OK, tout va bien pour moi maintenant.

Merci pour ton expertise Grum.

Hors ligne

  •  » Plugins
  •  » [Résolu] AMetaData 0.5.2 bug ?

Pied de page des forums

Propulsé par FluxBB

github twitter facebook newsletter Faire un don Piwigo.org © 2002-2020 · Contact