ZZZ http://zzz.rezo.net/ une sorte de fatras... fr SPIP - www.spip.net <span class="caps">ZZZ</span> http://zzz.rezo.net/local/cache-vignettes/L144xH93/siteon0-21452.png http://zzz.rezo.net/ 93 144 Télécharger flickrstore http://zzz.rezo.net/Telecharger-flickrstore.html http://zzz.rezo.net/Telecharger-flickrstore.html 2014-07-25T09:40:00Z text/html fr Fil <p>Pour Mac OS X Grâce à Platypus voici une version drag'n'drop pour Mac OS X. On peut : la lancer d'un double-clic pour récupérer les données de Flickr et poser les tags file:md5 sur les photos existantes ; déposer-glisser des fichiers image ou des répertoires pour les sauvegarder dans Flickr. flickrstore flickrstore est développé sous git : on peut le visualiser ici : (nouvelle version : juillet 2014). phpFlickr La librairie phpFlickr de Dan Coulter est téléchargeable depuis le site API key (...)</p> - <a href="http://zzz.rezo.net/-Flickr-Store-.html" rel="directory">Flickr Store</a> <div class='rss_texte'><h3 class='h3 spip'>Pour Mac <span class="caps">OS</span> X</h3> <p>Grâce à <a href="http://www.sveinbjorn.org/platypus" class='spip_out' rel='external'>Platypus</a> voici une version drag'n'drop pour Mac <span class="caps">OS</span> X. On peut :<br />— la lancer d'un double-clic pour récupérer les données de Flickr et poser les tags <code class='spip_code' dir='ltr'>file:md5</code> sur les photos existantes ;<br />— déposer-glisser des fichiers image ou des répertoires pour les sauvegarder dans Flickr.</p> <dl class='spip_document_64 spip_documents spip_documents_center'> <dt><a href='http://zzz.rezo.net/IMG/zip/Flickr_Store-2.zip' title='Zip - 191.7 ko' type="application/zip"><img src='http://zzz.rezo.net/local/cache-vignettes/L52xH52/zip-2bcd4.png' width='52' height='52' alt='Zip - 191.7 ko' style='height:52px;width:52px;' /></a></dt> <dt class='crayon document-titre-64 spip_doc_titre' style='width:120px;'><strong>Flickr Store 0.5 pour Mac <span class="caps">OS</span> X</strong></dt> </dl> <h3 class='h3 spip'>flickrstore</h3> <p><code class='spip_code' dir='ltr'>flickrstore</code> est développé sous git : on peut le visualiser ici :<br class='autobr' /> <a href="https://github.com/Fil/flickrstore" class='spip_url spip_out' rel='external'>https://github.com/Fil/flickrstore</a> (nouvelle version : juillet 2014).</p> <h3 class='h3 spip'>phpFlickr</h3> <p>La librairie phpFlickr de Dan Coulter est téléchargeable depuis le site <a href="http://phpflickr.com/" class='spip_url spip_out' rel='external'>http://phpflickr.com/</a></p> <h3 class='h3 spip'><span class="caps">API</span> key</h3> <p>Pour solliciter une clé rendez-vous sur le site Flickr, connectez-vous et allez à la page <a href="http://flickr.com/services/" class='spip_url spip_out' rel='external'>http://flickr.com/services/</a>. La clé doit ensuite être enregistrée dans le fichier <code class='spip_code' dir='ltr'>api_key.inc</code> à côté du fichier <code class='spip_code' dir='ltr'>flickrstore</code>.</p> <h3 class='h3 spip'>Une astuce : rotation automatique</h3> <p>Si comme moi vous sauvegardez le répertoire <code class='spip_code' dir='ltr'>iPhoto Library/Originals/</code>, les photos y sont conservées dans le sens horizontal. Mais certains appareils signalent qu'on peut les redresser en vertical, le cas échéant. Flickr sait détecter ce signal : il faut activer l'option sur la page <a href="http://www.flickr.com/account/prefs/autorotate/" class='spip_url spip_out' rel='external'>http://www.flickr.com/account/prefs...</a>.</p></div> Poids total http://zzz.rezo.net/Poids-total.html http://zzz.rezo.net/Poids-total.html 2008-12-19T15:57:18Z text/html fr Fil <p>Pour mesurer le total du poids des photos il suffit de sommer les valeurs des tags file:bytes= : class flickrstore extends phpFlickr ... function total_bytes() $this->get_allTags(); $total = 0; foreach($this->tags as $tag => $a) if (preg_match(',^file:bytes=([0-9]+),S', $tag, $r)) $total += count($a) * $r[1]; return $total; On obtient dès lors : // Write the total number of photos/bytes error_log(count($f->photos)." items"); (...)</p> - <a href="http://zzz.rezo.net/-Flickr-Store-.html" rel="directory">Flickr Store</a> <div class='rss_texte'><p>Pour mesurer le total du poids des photos il suffit de sommer les valeurs des tags <code class='spip_code' dir='ltr'>file:bytes=</code> :</p> <form action='' method='get'><div> <input type='hidden' name='exec' value='' /> <textarea readonly='readonly' cols='40' rows='12' class='spip_cadre' dir='ltr'>class flickrstore extends phpFlickr { ... function total_bytes() { $this->get_allTags(); $total = 0; foreach($this->tags as $tag => $a) { if (preg_match(',^file:bytes=([0-9]+),S', $tag, $r)) $total += count($a) * $r[1]; } return $total; }</textarea></div></form> <p>On obtient dès lors :</p> <form action='' method='get'><div> <input type='hidden' name='exec' value='' /> <textarea readonly='readonly' cols='40' rows='4' class='spip_cadre' dir='ltr'>// Write the total number of photos/bytes error_log(count($f->photos)." items"); error_log("total: ". (0.01*intval($f->total_bytes() /1024/1024/1024*100))." Gb");</textarea></div></form> <div style='text-align: left;' class='spip_code' dir='ltr'><code>14390 items<br /> total: 14.55 Gb</code></div></div> Upload d'images http://zzz.rezo.net/Upload-d-images.html http://zzz.rezo.net/Upload-d-images.html 2008-12-19T13:44:57Z text/html fr Fil <p>Une fois les tags file:md5 apposés à toutes les photos présentes sur le compte Flickr, on peut tranquillement scanner notre disque dur et uploader les photos qui ne correspondent pas aux tags md5 existants. La seule nouveauté en termes d'API Flickr est ici l'appel à la méthode sync_upload : $r = $this->sync_upload( $file, null, /* title */ null, /* description */ $tags, /* tags */ 0, /* is_public */ (...)</p> - <a href="http://zzz.rezo.net/-Flickr-Store-.html" rel="directory">Flickr Store</a> <div class='rss_texte'><p>Une fois les tags <code class='spip_code' dir='ltr'>file:md5</code> apposés à toutes les photos présentes sur le compte Flickr, on peut tranquillement scanner notre disque dur et uploader les photos qui ne correspondent pas aux tags md5 existants.</p> <p>La seule nouveauté en termes d'<span class="caps">API</span> Flickr est ici l'appel à la méthode <code class='spip_code' dir='ltr'>sync_upload</code> :</p> <form action='' method='get'><div> <input type='hidden' name='exec' value='' /> <textarea readonly='readonly' cols='40' rows='9' class='spip_cadre' dir='ltr'>$r = $this->sync_upload( $file, null, /* title */ null, /* description */ $tags, /* tags */ 0, /* is_public */ 0, /* is_friend */ 0 /* is_family */ );</textarea></div></form> <p>Cet appel est enveloppé dans du php qui scanne récursivement un répertoire et uploade chaque fichier .png ou .jpg qu'il trouve.</p> <form action='' method='get'><div> <input type='hidden' name='exec' value='' /> <textarea readonly='readonly' cols='40' rows='40' class='spip_cadre' dir='ltr'>class flickrStore extends phpFlickr { ... function upload_files($file) { if (is_file($file) AND is_readable($file) AND preg_match(',\.(jpe?g|png)$,iS', $file)) { $md5 = 'file:md5='.md5_file($file); if ($this->tags[$md5]) { error_log("$file is up: $md5 : ".join(' ', $this->tags[$md5])); return true; } $tags = $md5.' file:bytes='.filesize($file); error_log("Uploading $file"); $r = $this->sync_upload( $file, null, /* title */ null, /* description */ $tags, /* tags */ 0, /* is_public */ 0, /* is_friend */ 0 /* is_family */ ); if ($r) { $this->tags[$md5] = array($r); error_log("Image uploaded: $r"); @unlink(_PREFS.'cache.txt'); } error_log("Image not uploaded"); return false; } else if (is_dir($file) AND is_readable($file)) { if ($h = opendir($file)) { while (false !== ($next = readdir($h))) if ($next != '.' AND $next != '..') $this->upload_files("$file/$next"); closedir($h); } } }</textarea></div></form> <p>Ce qui donne notre script final : la première fois qu'il est invoqué, il appose le tag <code class='spip_code' dir='ltr'>file:md5</code> à toutes les photos du compte Flickr. Les fois suivantes il télécharge les fichiers (et les répertoires, de façon récursive), dans le compte.</p> <form action='' method='get'><div> <input type='hidden' name='exec' value='' /> <textarea readonly='readonly' cols='40' rows='23' class='spip_cadre' dir='ltr'>// MAIN // arguments = directories or files to scan $files = $argv; array_shift($files); // initialize $f = new flickrStore(_flickr_api_key, _flickr_api_secret); $token = $f->auth_desktop("write"); $f->setToken($token['token']); // retrieve all pictres data from flickr $f->get_allPhotos(); // tag non-tagged images $f->set_md5tag_all(); // get all current tags $f->get_allTags(); // scan directories and files, and upload new ones foreach($files as $file) $f->upload_files($file);</textarea></div></form></div> Le tag file:md5 http://zzz.rezo.net/Le-tag-file-md5.html http://zzz.rezo.net/Le-tag-file-md5.html 2008-12-19T13:05:52Z text/html fr Fil <p>Notre problématique est de pouvoir faire une sauvegarde de toutes nos photos sur Flickr. Pour cela il faut savoir si telle photo présente sur le disque dur est ou non déjà sur le site. On pourrait enregistrer dans une base de données locale une série de couples (chemin de la photo, id flickr), mais cela présente de nombreux inconvénients : si la même image figure deux fois sur notre disque, on va la télécharger deux fois ; si notre base de données locale disparaît, on ne peut plus dédoublonner (...)</p> - <a href="http://zzz.rezo.net/-Flickr-Store-.html" rel="directory">Flickr Store</a> <div class='rss_texte'><p>Notre problématique est de pouvoir faire une sauvegarde de toutes nos photos sur Flickr. Pour cela il faut savoir si telle photo présente sur le disque dur est ou non déjà sur le site. On pourrait enregistrer dans une base de données locale une série de couples <code class='spip_code' dir='ltr'>(chemin de la photo, id flickr)</code>, mais cela présente de nombreux inconvénients :</p> <p>— si la même image figure deux fois sur notre disque, on va la télécharger deux fois ;<br />— si notre base de données locale disparaît, on ne peut plus dédoublonner notre base.</p> <p>Pour contourner ce problème on introduit un tag <code class='spip_code' dir='ltr'>file:md5=xxxx</code>, où <code class='spip_code' dir='ltr'>xxx</code> est la signature md5 du fichier de la photo. Cette signature se calcule en php de la façon suivante :</p> <form action='' method='get'><div> <input type='hidden' name='exec' value='' /> <textarea readonly='readonly' cols='40' rows='2' class='spip_cadre' dir='ltr'>$md5 = md5_file($file);</textarea></div></form> <p>Cette notation correspond aux <code class='spip_code' dir='ltr'>machine tags</code> recommandés par Flickr pour tous les tags traités de façon automatique <i>cf.</i> <a href="http://www.flickr.com/groups/api/discuss/72157594497877875/" class='spip_url spip_out' rel='external'>http://www.flickr.com/groups/api/di...</a>.</p> <p>Ce tag devra être apposé à chaque photo uploadée sur le site ; à partir de là nous saurons, en calculant la signature md5 de n'importe quel fichier de notre disque dur, si ce fichier a déjà été uploadé ou non : il suffira de regarder dans <code class='spip_code' dir='ltr'>$photos</code> si une photo porte ce tag.</p> <h3 class='h3 spip'>Apposer le tag <code class='spip_code' dir='ltr'>file:md5</code> aux photos déjà uploadées</h3> <p>Si vous avez déjà uploadé des fichiers sur votre compte Flickr, il peut être judicieux de les tagguer avec ce système, de manière à éviter de les redoublonner par la suite. Pour cela, pas de miracle, il faut les télécharger une par une, calculer leur signature, et apposer le tag. Nous en profiterons pour apposer un second tag automatique <code class='spip_code' dir='ltr'>file:bytes</code> indiquant la taille (en octets) du fichier.</p> <p>Ce qui donne :</p> <form action='' method='get'><div> <input type='hidden' name='exec' value='' /> <textarea readonly='readonly' cols='40' rows='55' class='spip_cadre' dir='ltr'>class flickrStore extends phpFlickr { ... // Tag md5 a certain photo already on flickr function set_md5tag($id) { // Check that id exists if (!$this->photos[$id]) { error_log("photo $id does not exist"); return false; } // Check that the md5 tag is not already there if (preg_match(',\bfile:md5=[0-9a-f]{32},S', $this->photos[$id]['tags'])) { error_log("$id: already tagged md5"); return true; } // Download (!) the original file and compute its tag $original = $this->buildPhotoURL($this->photos[$id], 'original'); error_log("$id: downloading $original"); if (!$im = file_get_contents($original)) { error_log("http error"); return false; } $tags = array('file:md5='.md5($im), 'file:bytes='.strlen($im)); unset($im); // tag the image on Flickr and in our local cache if ($this->photos_addTags($id, join(',',$tags))) { $this->photos[$id]['tags'] = join(' ', array_merge(explode($this->photos[$id]['tags'], ' '), $tags)); file_set_contents(_PREFS.'cache.txt', serialize($this->photos)); error_log($this->photos[$id]['tags']); return true; } error_log("Could not tag"); return false; } function set_md5tag_all() { foreach($this->photos as $photo) $this->set_md5tag($photo['id']); } } // MAIN $f = new flickrStore(_flickr_api_key, _flickr_api_secret); $token = $f->auth_desktop("write"); $f->setToken($token['token']); $f->get_allPhotos(); $f->set_md5tag_all();</textarea></div></form> <p>Chaque photo non tagguée sera alors téléchargée, analysée puis tagguée :</p> <div style='text-align: left;' class='spip_code' dir='ltr'><code>3120529098: already tagged md5<br /> 3120529078: downloading http://farm4.static.flickr.com/3204/3119700509_3d3cb5c693_o.jpg<br /> file:md5=5d43f273a2b5003b57273b227116a708 file:bytes=2581222</code></div></div> Etablir la liste de nos photos http://zzz.rezo.net/Etablir-la-liste-de-nos-photos.html http://zzz.rezo.net/Etablir-la-liste-de-nos-photos.html 2008-12-19T11:34:13Z text/html fr Fil <p>Maintenant qu'on est connecté et authentifié, on va récupérer la liste de nos photos sur le site. Ici c'est très simple ; on utilise la requête flickr.photos.search en précisant 'user_id'=>$token['user']['nsid'] : $a = $f->photos_search(array( 'user_id'=>$token['user']['nsid'] )) ; foreach ($a['photo'] as $photo) echo $f->buildPhotoURL($photo)." ".$photo['title']."\n" ; Et on obtient : http://farm4.static.flickr.com/3219/3118382945_eeca6f02c1.jpg Futur couloir (...)</p> - <a href="http://zzz.rezo.net/-Flickr-Store-.html" rel="directory">Flickr Store</a> <div class='rss_texte'><p>Maintenant qu'on est connecté et authentifié, on va récupérer la liste de nos photos sur le site.</p> <p>Ici c'est très simple ; on utilise la requête <code class='spip_code' dir='ltr'>flickr.photos.search</code> en précisant <code class='spip_code' dir='ltr'>'user_id'=>$token['user']['nsid']</code> :</p> <form action='' method='get'><div> <input type='hidden' name='exec' value='' /> <textarea readonly='readonly' cols='40' rows='6' class='spip_cadre' dir='ltr'>$a = $f->photos_search(array( 'user_id'=>$token['user']['nsid'] )); foreach ($a['photo'] as $photo) echo $f->buildPhotoURL($photo)." ".$photo['title']."\n";</textarea></div></form> <p>Et on obtient :</p> <div style='text-align: left;' class='spip_code' dir='ltr'><code>http://farm4.static.flickr.com/3219/3118382945_eeca6f02c1.jpg Futur couloir<br /> http://farm4.static.flickr.com/3131/3118355155_a9ed8ab55d.jpg Artefact<br /> http://farm4.static.flickr.com/3127/3118255815_a443427c23.jpg Pressoir<br /> http://farm4.static.flickr.com/3126/3118131019_41ee8b848b.jpg Passerelle<br /> http://farm4.static.flickr.com/3178/3118887176_fd7c172ebd.jpg Le puits<br /> http://farm4.static.flickr.com/3294/3118651022_d1bac3307a.jpg Muizenberg<br /> ...</code></div> <p>La liste ne contient que les photos publiques, car on n'a pas utilisé notre <code class='spip_code' dir='ltr'>token</code> :</p> <form action='' method='get'><div> <input type='hidden' name='exec' value='' /> <textarea readonly='readonly' cols='40' rows='4' class='spip_cadre' dir='ltr'>$f->setToken($token['token']); $a = $f->photos_search(array( 'user_id'=> 'me' ));</textarea></div></form> <p>Ici, comme on donne le <code class='spip_code' dir='ltr'>token</code>, il n'est pas nécessaire de préciser le <code class='spip_code' dir='ltr'>user_id</code> ; on peut se contenter du raccourci <code class='spip_code' dir='ltr'>me</code>.</p> <p>On remarque maintenant que la liste est limitée aux 100 dernières images uploadées sur le site. L'<span class="caps">API</span> permet une pagination, mais limite de toutes façons les requêtes à 500 images : il faudra donc faire plusieurs appels pour être sûr de tout récupérer. On crée donc une nouvelle méthode :</p> <form action='' method='get'><div> <input type='hidden' name='exec' value='' /> <textarea readonly='readonly' cols='40' rows='21' class='spip_cadre' dir='ltr'>class flickrStore extends phpFlickr { function get_allPhotos($uid = 'me') { $page = 1; $photos = array(); do { error_log("Requesting page $page". ($pages ? "/$pages" : '')); $a = $this->photos_search(array( 'user_id'=> $uid, 'per_page' => 500, 'page' => $page, 'extras' => 'original_format,date_taken,tags' )); $pages = $a['pages']; foreach ($a['photo'] as $p) $photos[$p['id']] = $p; } while ($page++ < $pages); return $photos; } }</textarea></div></form> <p>A noter : notre requête demande plusieurs <code class='spip_code' dir='ltr'>extras</code> : <code class='spip_code' dir='ltr'>original_format,date_taken,tags</code>, métadonnées dont nous auront besoin par la suite.</p> <p>Et voilà :</p> <form action='' method='get'><div> <input type='hidden' name='exec' value='' /> <textarea readonly='readonly' cols='40' rows='7' class='spip_cadre' dir='ltr'>$f = new flickrStore(_flickr_api_key, _flickr_api_secret); $token = $f->auth_desktop("read"); $f->setToken($token['token']); $a = $f->get_allPhotos(); foreach ($a as $photo) echo $f->buildPhotoURL($photo)." ".$photo['title']."\n";</textarea></div></form> <div style='text-align: left;' class='spip_code' dir='ltr'><code>Requesting page 1<br /> Requesting page 2/28<br /> Requesting page 3/28<br /> ...<br /> Requesting page 28/28<br /> http://farm4.static.flickr.com/3247/3120416254_a524856996.jpg DSC02696<br /> http://farm4.static.flickr.com/3087/3119587359_ae811001f1.jpg DSC02695<br /> http://farm4.static.flickr.com/3197/3119586965_c55da65949.jpg DSC02694<br /> http://farm4.static.flickr.com/3241/3119586575_a3164da6c1.jpg DSC02693<br /> http://farm4.static.flickr.com/3197/3119586129_44cf8184f7.jpg DSC02692<br /> http://farm4.static.flickr.com/3216/3120413986_231c8b8ea4.jpg DSC02691<br /> ...</code></div> <p>Bien entendu, comme il peut y avoir beaucoup de photos (j'en ai plus de 15 000), on va mettre ça en cache, cache qu'on va invalider dès qu'il sera jugé trop vieux.</p> <form action='' method='get'><div> <input type='hidden' name='exec' value='' /> <textarea readonly='readonly' cols='40' rows='8' class='spip_cadre' dir='ltr'>if (@filemtime(_PREFS.'cache.txt') < time()-10*60 OR !$photos = @unserialize(file_get_contents(_PREFS.'cache.txt'))) { $photos = $f->get_allPhotos(); set_file_contents(_PREFS.'cache.txt', serialize($photos)); } else error_log("Getting photos from cache");</textarea></div></form> <p>On peut maintenant jouer avec ces données, pour afficher les titres, ou les tags etc. :</p> <form action='' method='get'><div> <input type='hidden' name='exec' value='' /> <textarea readonly='readonly' cols='40' rows='2' class='spip_cadre' dir='ltr'>foreach ($photos as $photo) echo $photo['id'].' - '.$photo['tags']."\n";</textarea></div></form> <p>La structure de <code class='spip_code' dir='ltr'>$photo</code> est la suivante :</p> <div style='text-align: left;' class='spip_code' dir='ltr'><code>Array<br /> (<br /> [id] => 3119605761<br /> [owner] => 82626280@N00<br /> [secret] => db062ac947<br /> [server] => 3295<br /> [farm] => 4<br /> [title] => DSC02740<br /> [ispublic] => 0<br /> [isfriend] => 0<br /> [isfamily] => 0<br /> [originalsecret] => 856912a29f<br /> [originalformat] => jpg<br /> [datetaken] => 2008-06-08 10:40:28<br /> [datetakengranularity] => 0<br /> [tags] => upload test fil<br /> )</code></div> <p>Ces données permettent de savoir si la photo est publique ou privée, réservée à la famille ou aux amis ; elles contiennent aussi titre, date de prise de vue, tags, ainsi qu'un « secret » qui permet de déterminer l'<span class="caps">URL</span> de la photo même si elle est privée.</p></div> Authentifier notre application sur Flickr http://zzz.rezo.net/Authentifier-notre-application-sur.html http://zzz.rezo.net/Authentifier-notre-application-sur.html 2008-12-19T10:53:15Z text/html fr Fil <p>Si l'on souhaite exploiter nos photos perso sur notre compte, notamment pour lire les photos privées ou en ajouter de nouvelles, il faut maintenant pouvoir s'authentifier. C'est la partie la plus compliquée du script. Le principe consiste à demander un code frob, puis à le faire autoriser par l'utilisateur. Une fois ce frob autorisé, on obtient un token, qu'on stocke précieusement car il constitue notre ticket d'entrée authentifiée sur l'API. Nous allons enregistrer notre application comme « Desktop (...)</p> - <a href="http://zzz.rezo.net/-Flickr-Store-.html" rel="directory">Flickr Store</a> <div class='rss_texte'><p>Si l'on souhaite exploiter nos photos perso sur notre compte, notamment pour lire les photos privées ou en ajouter de nouvelles, il faut maintenant pouvoir s'authentifier. C'est la partie la plus compliquée du script.</p> <p>Le principe consiste à demander un code <code class='spip_code' dir='ltr'>frob</code>, puis à le faire autoriser par l'utilisateur. Une fois ce <code class='spip_code' dir='ltr'>frob</code> autorisé, on obtient un <code class='spip_code' dir='ltr'>token</code>, qu'on stocke précieusement car il constitue notre ticket d'entrée authentifiée sur l'<span class="caps">API</span>.</p> <p>Nous allons enregistrer notre application comme « Desktop App », en cochant la case correspondante dans les réglages de l'<span class="caps">API</span> key sur le site Flickr :<br class='autobr' /> <span class='spip_document_1 spip_documents spip_documents_center'> <img src='http://zzz.rezo.net/local/cache-vignettes/L282xH81/Image_1-55bff.png' width='282' height='81' alt="" style='height:81px;width:282px;' /></span></p> <p>Tout d'abord, une fonction pour écrire dans un fichier :</p> <form action='' method='get'><div> <input type='hidden' name='exec' value='' /> <textarea readonly='readonly' cols='40' rows='9' class='spip_cadre' dir='ltr'>// file_set_contents to write a file function file_set_contents($file, $content) { if (!$fh = fopen($file, 'wb') OR !fwrite($fh, $content) OR !fclose($fh) OR !(filesize($file) == strlen($content))) return false; return true; }</textarea></div></form> <p>et voici notre code pour demander un frob, donner à l'utilisateur l'url de validation, puis au tour suivant demander un token :</p> <form action='' method='get'><div> <input type='hidden' name='exec' value='' /> <textarea readonly='readonly' cols='40' rows='50' class='spip_cadre' dir='ltr'>class flickrStore extends phpFlickr { function auth_desktop($perms) { if (!$token = @unserialize(file_get_contents(_PREFS.'token.txt'))) { if (!$frob = @file_get_contents(_PREFS.'frob.txt')) { echo "Requesting a new frob...\n"; $frob = $this->auth_getFrob(); file_set_contents(_PREFS.'frob.txt', $frob); } if (!$frob) die ("Couldn't get no frob\n"); echo "Requesting a token...\n"; if ($token = $this->auth_getToken($frob)) { file_set_contents(_PREFS.'token.txt', serialize($token)); @unlink(_PREFS.'frob.txt'); } } if (!$token) { echo 'error '.$this->error_code.': '.$this->error_msg . "\n"; echo "We are not authenticated\n"; echo "Please follow this link to authorize the application:\n"; $api_sig = md5($this->secret . "api_key" . $this->api_key . "frob" . $frob . "perms" . $perms); echo "http://www.flickr.com/services/auth/?api_key=" . $this->api_key . "&frob=" . $frob . "&perms=" . $perms . "&api_sig=". $api_sig; echo "\n"; exit; } return $token; } } // MAIN $f = new flickrStore(_flickr_api_key, _flickr_api_secret); $token = $f->auth_desktop("delete"); print_r($token);</textarea></div></form> <p>On obtient alors notre sésame :</p> <div style='text-align: left;' class='spip_code' dir='ltr'><code>Array<br /> (<br /> [token] => 72157611262255979-3d38abdacbcf5df0<br /> [perms] => delete<br /> [user] => Array<br /> (<br /> [nsid] => 82626280@N00<br /> [username] => Fil+<br /> [fullname] => Fil<br /> )<br /> )</code></div> <p>Les différents niveaux de permission sont <code class='spip_code' dir='ltr'>read</code>, <code class='spip_code' dir='ltr'>write</code>, <code class='spip_code' dir='ltr'>delete</code>. Ici on choisit <code class='spip_code' dir='ltr'>delete</code> pour avoir les coudées franches, mais si votre application ne fait que de la lecture des données, il est préférable d'utiliser <code class='spip_code' dir='ltr'>read</code>, et si elle modifie (par exemple titre ou tags) mais n'efface jamais de photo : <code class='spip_code' dir='ltr'>write</code> suffit.</p> <blockquote class="spip"> <p><br class='autobr' /> A noter : on enregistre le <code class='spip_code' dir='ltr'>frob</code> puis le <code class='spip_code' dir='ltr'>token</code> dans le répertoire de préférences <code class='spip_code' dir='ltr'>~user/.flickrstore/</code> ; en cas d'échec il faut effacer ces fichiers pour recommencer.</p> <p>L'authentification décrite ici correspond à l'authentification « desktop » pour un script lancé en ligne de commande. Pour l'authentification « web », c'est différent : le <code class='spip_code' dir='ltr'>token</code> sera enregistré dans la session de l'utilisateur ; on pourra diriger automatiquement le navigateur sur l'<span class="caps">URL</span> de confirmation, qui le redirigera à son tour, après avoir validé le <code class='spip_code' dir='ltr'>frob</code>, sur une adresse <code class='spip_code' dir='ltr'>callback</code> qu'on aura fournie dans les réglages de l'<span class="caps">API</span> key sur le site.</p> </blockquote></div> Se connecter à Flickr http://zzz.rezo.net/Se-connecter-a-Flickr.html http://zzz.rezo.net/Se-connecter-a-Flickr.html 2008-12-19T09:17:39Z text/html fr Fil <p>Nous ferons usage de la librairie phpFlickr développée par Dan Coulter pour piloter l'interface de programmation (API) de Flickr . Un script PHP en ligne de commande Première étape : créer un script PHP accessible en ligne de commande. Pour cela il faut vérifier que php est exécutable sur la machine : # !/usr/bin/env php On stocke ce script dans le fichier flickrstore et on l'invoque en le rendant exécutable (chmod +x flickrstore), puis en l'appelant en ligne de commande : > ./flickrstore php (...)</p> - <a href="http://zzz.rezo.net/-Flickr-Store-.html" rel="directory">Flickr Store</a> <div class='rss_texte'><p>Nous ferons usage de la librairie <code class='spip_code' dir='ltr'>phpFlickr</code> <a href="http://phpflickr.com/" class='spip_url spip_out' rel='external'>http://phpflickr.com/</a> développée par <a href="http://dancoulter.com/" class='spip_out' rel='external'>Dan Coulter</a> pour piloter l'interface de programmation (<span class="caps">API</span>) de Flickr <a href="http://flickr.com/services/api/" class='spip_url spip_out' rel='external'>http://flickr.com/services/api/</a>.</p> <h3 class='h3 spip'>Un script <span class="caps">PHP</span> en ligne de commande</h3> <p>Première étape : créer un script <span class="caps">PHP</span> accessible en ligne de commande. Pour cela il faut vérifier que <code class='spip_code' dir='ltr'>php</code> est exécutable sur la machine :</p> <form action='' method='get'><div> <input type='hidden' name='exec' value='' /> <textarea readonly='readonly' cols='40' rows='3' class='spip_cadre' dir='ltr'>#!/usr/bin/env php <?php echo "php OK\n";</textarea></div></form> <p>On stocke ce script dans le fichier <code class='spip_code' dir='ltr'>flickrstore</code> et on l'invoque en le rendant exécutable (<code class='spip_code' dir='ltr'>chmod +x flickrstore</code>), puis en l'appelant en ligne de commande :</p> <div style='text-align: left;' class='spip_code' dir='ltr'><code>> ./flickrstore<br /> php OK</code></div> <p>Quelques lignes de code supplémentaires permettront de vérifier qu'on dispose bien d'une version de <span class="caps">PHP</span> suffisamment récente et dotée des librairies indispensables.</p> <p>Il faut notamment télécharger <code class='spip_code' dir='ltr'>phpFlickr</code>, en prenant le paquet zip proposé sur le site <a href="http://phpFlickr.com/" class='spip_url spip_out' rel='external'>http://phpFlickr.com/</a>.</p> <h3 class='h3 spip'>Créer un objet phpFlickr</h3> <p>On va ensuite instancier un objet phpFlickr. Celui-ci est doté de méthodes (fonctions) qui lui permettent de dialoguer avec l'<span class="caps">API</span> de Flickr. Flickr exige de pouvoir contrôler l'usage fait par les différents scripts qui exploitent son <span class="caps">API</span> : pour cela ils imposent au développeur de solliciter une clé sur leur site. Cette clé se compose de deux parties : <code class='spip_code' dir='ltr'>key</code> et <code class='spip_code' dir='ltr'>secret</code>, que nous obtenons sur <a href="http://flickr.com/services/api" class='spip_url spip_out' rel='external'>http://flickr.com/services/api</a> (“Apply for a new <span class="caps">API</span> key”) et stockons dans un fichier <code class='spip_code' dir='ltr'>api_key.inc</code> :</p> <form action='' method='get'><div> <input type='hidden' name='exec' value='' /> <textarea readonly='readonly' cols='40' rows='4' class='spip_cadre' dir='ltr'><?php define('_flickr_api_key', '18ed9ebf39dca0a798eca25425ebfeb4'); define('_flickr_api_secret', '1649195891888b0c');</textarea></div></form> <p>Dans ce premier exemple nous lui faisons lister les deux photos les plus récentes du site.</p> <form action='' method='get'><div> <input type='hidden' name='exec' value='' /> <textarea readonly='readonly' cols='40' rows='22' class='spip_cadre' dir='ltr'>#!/usr/bin/env php <?php // Check php version and set a few constants function checkenv() { define('__DIR__', realpath(dirname(__FILE__)).'/'); require_once __DIR__.'api_key.inc'; } // Include phpFlickr function include_phpFlickr() { require_once __DIR__.'phpFlickr-2.3.0.1/phpFlickr.php'; } // MAIN checkenv(); include_phpFlickr(); $f = new phpFlickr(_flickr_api_key, _flickr_api_secret); // Show 2 most recent pictures $b = $f->photos_getRecent(null,2); print_r($b);</textarea></div></form> <p>Le résultat est un tableau en <span class="caps">PHP</span> qui donne les éléments d'identification de ces deux photos :</p> <div style='text-align: left;' class='spip_code' dir='ltr'><code>Array<br /> (<br /> [page] => 1<br /> [pages] => 500<br /> [perpage] => 2<br /> [total] => 1000<br /> [photo] => Array<br /> (<br /> [0] => Array<br /> (<br /> [id] => 3120281934<br /> [owner] => 21199371@N04<br /> [secret] => 1d21294ec4<br /> [server] => 3143<br /> [farm] => 4<br /> [title] => 05122008094<br /> [ispublic] => 1<br /> [isfriend] => 0<br /> [isfamily] => 0<br /> )<br /> <br /> [1] => Array<br /> (<br /> [id] => 3120281900<br /> [owner] => 29002449@N02<br /> [secret] => 28aa2e5344<br /> [server] => 3179<br /> [farm] => 4<br /> [title] => IMG_0764<br /> [ispublic] => 1<br /> [isfriend] => 0<br /> [isfamily] => 0<br /> )<br /> )<br /> )</code></div> <p>La librairie phpFlickr propose une méthode permettant de calculer l'<span class="caps">URL</span> d'une photo à partir de son identification (<i>cf.</i> <a href="http://www.flickr.com/services/api/misc.urls.html" class='spip_url spip_out' rel='external'>http://www.flickr.com/services/api/...</a>) :</p> <form action='' method='get'><div> <input type='hidden' name='exec' value='' /> <textarea readonly='readonly' cols='40' rows='3' class='spip_cadre' dir='ltr'>foreach($b['photo'] as $photo) echo $f->buildPhotoURL($photo)." ".$photo['title']."\n";</textarea></div></form> <p>donne :</p> <div style='text-align: left;' class='spip_code' dir='ltr'><code>http://farm4.static.flickr.com/3179/3120286846_60e3f471e6.jpg IMG_1613<br /> http://farm4.static.flickr.com/3121/3119459869_9af9bb32a6.jpg Imari</code></div></div>