source: trunk/tools/create_listing_file.php @ 1229

Last change on this file since 1229 was 1229, checked in by rvelices, 18 years ago

merge r1228 from branch-1_6 into trunk

bug 345: cannot browse categories (Club Internet modified web server provides
PATH_INFO even if it is empty)

fix 339: also added in create_listing_file.php

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.7 KB
Line 
1<?php
2// +-----------------------------------------------------------------------+
3// | PhpWebGallery - a PHP based picture gallery                           |
4// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
5// | Copyright (C) 2003-2005 PhpWebGallery Team - http://phpwebgallery.net |
6// +-----------------------------------------------------------------------+
7// | branch        : BSF (Best So Far)
8// | file          : $RCSfile$
9// | last update   : $Date: 2006-04-21 00:04:11 +0000 (Fri, 21 Apr 2006) $
10// | last modifier : $Author: rvelices $
11// | revision      : $Revision: 1229 $
12// +-----------------------------------------------------------------------+
13// | This program is free software; you can redistribute it and/or modify  |
14// | it under the terms of the GNU General Public License as published by  |
15// | the Free Software Foundation                                          |
16// |                                                                       |
17// | This program is distributed in the hope that it will be useful, but   |
18// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
19// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
20// | General Public License for more details.                              |
21// |                                                                       |
22// | You should have received a copy of the GNU General Public License     |
23// | along with this program; if not, write to the Free Software           |
24// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
25// | USA.                                                                  |
26// +-----------------------------------------------------------------------+
27
28// +-----------------------------------------------------------------------+
29// |                              parameters                               |
30// +-----------------------------------------------------------------------+
31
32// prefix for thumbnails in "thumbnail" sub directories
33$conf['prefix_thumbnail'] = 'TN-';
34
35// $conf['file_ext'] lists all extensions (case insensitive) allowed for
36// your PhpWebGallery installation
37$conf['file_ext'] = array('jpg','JPG','png','PNG','gif','GIF','mpg','zip',
38                          'avi','mp3','ogg');
39
40// $conf['picture_ext'] must be a subset of $conf['file_ext']
41$conf['picture_ext'] = array('jpg','JPG','png','PNG','gif','GIF');
42
43// $conf['version'] is used to verify the compatibility of the generated
44// listing.xml file and the PhpWebGallery version you're running
45$conf['version'] = '%PWGVERSION%';
46
47// $conf['use_exif'] set to true if you want to use Exif information
48$conf['use_exif'] = true;
49
50// use_exif_mapping: same behaviour as use_iptc_mapping
51$conf['use_exif_mapping'] = array(
52  'date_creation' => 'DateTimeOriginal'
53  );
54
55// $conf['use_iptc'] set to true if you want to use IPTC informations of the
56// element according to get_sync_iptc_data function mapping, otherwise, set
57// to false
58$conf['use_iptc'] = false;
59
60// use_iptc_mapping : in which IPTC fields will PhpWebGallery find image
61// information ? This setting is used during metadata synchronisation. It
62// associates a phpwebgallery_images column name to a IPTC key
63$conf['use_iptc_mapping'] = array(
64  'keywords'        => '2#025',
65  'date_creation'   => '2#055',
66  'author'          => '2#122',
67  'name'            => '2#005',
68  'comment'         => '2#120'
69  );
70
71// +-----------------------------------------------------------------------+
72// |                               functions                               |
73// +-----------------------------------------------------------------------+
74
75/**
76 * returns informations from IPTC metadata, mapping is done at the beginning
77 * of the function
78 *
79 * @param string $filename
80 * @return array
81 */
82function get_iptc_data($filename, $map)
83{
84  $result = array();
85
86  // Read IPTC data
87  $iptc = array();
88
89  $imginfo = array();
90  getimagesize($filename, $imginfo);
91
92  if (isset($imginfo['APP13']))
93  {
94    $iptc = iptcparse($imginfo['APP13']);
95    if (is_array($iptc))
96    {
97      $rmap = array_flip($map);
98      foreach (array_keys($rmap) as $iptc_key)
99      {
100        if (isset($iptc[$iptc_key][0]))
101        {
102          if ($iptc_key == '2#025')
103          {
104            $value = implode(',',
105                             array_map('clean_iptc_value',$iptc[$iptc_key]));
106          }
107          else
108          {
109            $value = clean_iptc_value($iptc[$iptc_key][0]);
110          }
111
112          foreach (array_keys($map, $iptc_key) as $pwg_key)
113          {
114            $result[$pwg_key] = $value;
115          }
116        }
117      }
118    }
119  }
120  return $result;
121}
122
123/**
124 * return a cleaned IPTC value
125 *
126 * @param string value
127 * @return string
128 */
129function clean_iptc_value($value)
130{
131  // strip leading zeros (weird Kodak Scanner software)
132  while ($value[0] == chr(0))
133  {
134    $value = substr($value, 1);
135  }
136  // remove binary nulls
137  $value = str_replace(chr(0x00), ' ', $value);
138
139  return htmlentities($value);
140}
141
142function get_sync_iptc_data($file)
143{
144  global $conf;
145
146  $map = $conf['use_iptc_mapping'];
147  $datefields = array('date_creation', 'date_available');
148
149  $iptc = get_iptc_data($file, $map);
150
151  foreach ($iptc as $pwg_key => $value)
152  {
153    if (in_array($pwg_key, $datefields))
154    {
155      if ( preg_match('/(\d{4})(\d{2})(\d{2})/', $value, $matches))
156      {
157        $iptc[$pwg_key] = $matches[1].'-'.$matches[2].'-'.$matches[3];
158      }
159    }
160  }
161
162  if (isset($iptc['keywords']))
163  {
164    // official keywords separator is the comma
165    $iptc['keywords'] = preg_replace('/[.;]/', ',', $iptc['keywords']);
166    $iptc['keywords'] = preg_replace('/^,+|,+$/', '', $iptc['keywords']);
167  }
168  $iptc['keywords'] = implode(
169               ',',
170               array_unique(
171                 explode(
172                   ',',
173                   $iptc['keywords']
174                   )
175                 )
176               );
177  return $iptc;
178}
179
180/**
181 * returns a float value coresponding to the number of seconds since the
182 * unix epoch (1st January 1970) and the microseconds are precised :
183 * e.g. 1052343429.89276600
184 *
185 * @return float
186 */
187function get_moment()
188{
189  $t1 = explode(' ', microtime());
190  $t2 = explode('.', $t1[0]);
191  $t2 = $t1[1].'.'.$t2[1];
192  return $t2;
193}
194
195/**
196 * returns the number of seconds (with 3 decimals precision) between the
197 * start time and the end time given.
198 *
199 * @param float start
200 * @param float end
201 * @return void
202 */
203function get_elapsed_time($start, $end)
204{
205  return number_format($end - $start, 3, '.', ' ').' s';
206}
207
208/**
209 * returns an array with all picture files according to $conf['file_ext']
210 *
211 * @param string $dir
212 * @return array
213 */
214function get_pwg_files($dir)
215{
216  global $conf;
217
218  $pictures = array();
219  if ($opendir = opendir($dir))
220  {
221    while ($file = readdir($opendir))
222    {
223      if (in_array(get_extension($file), $conf['file_ext']))
224      {
225        array_push($pictures, $file);
226        if (!preg_match('/^[a-zA-Z0-9-_.]+$/', $file))
227        {
228          echo 'PWG-WARNING-2: "'.$file.'" : ';
229          echo 'The name of the file should be composed of ';
230          echo 'letters, figures, "-", "_" or "." ONLY';
231          echo "\n";
232        }
233      }
234    }
235  }
236  return $pictures;
237}
238
239/**
240 * returns an array with all thumbnails according to $conf['picture_ext']
241 * and $conf['prefix_thumbnail']
242 *
243 * @param string $dir
244 * @return array
245 */
246function get_thumb_files($dir)
247{
248  global $conf;
249
250  $prefix_length = strlen($conf['prefix_thumbnail']);
251
252  $thumbnails = array();
253  if ($opendir = @opendir($dir.'/thumbnail'))
254  {
255    while ($file = readdir($opendir))
256    {
257      if (in_array(get_extension($file), $conf['picture_ext'])
258          and substr($file,0,$prefix_length) == $conf['prefix_thumbnail'])
259      {
260        array_push($thumbnails, $file);
261      }
262    }
263  }
264  return $thumbnails;
265}
266
267/**
268 * returns an array with representative picture files of a directory
269 * according to $conf['picture_ext']
270 *
271 * @param string $dir
272 * @return array
273 */
274function get_representative_files($dir)
275{
276  global $conf;
277
278  $pictures = array();
279  if ($opendir = @opendir($dir.'/pwg_representative'))
280  {
281    while ($file = readdir($opendir))
282    {
283      if (in_array(get_extension($file), $conf['picture_ext']))
284      {
285        array_push($pictures, $file);
286      }
287    }
288  }
289  return $pictures;
290}
291
292/**
293 * returns an array with high quality/resolution picture files of a directory
294 * according to $conf['picture_ext']
295 *
296 * @param string $dir
297 * @return array
298 */
299function get_high_files($dir)
300{
301  global $conf;
302
303  $pictures = array();
304  if ($opendir = @opendir($dir.'/pwg_high'))
305  {
306    while ($file = readdir($opendir))
307    {
308      if (in_array(get_extension($file), $conf['picture_ext']))
309      {
310        array_push($pictures, $file);
311      }
312    }
313  }
314  return $pictures;
315}
316
317/**
318 * search in $basedir the sub-directories and calls get_pictures
319 *
320 * @return void
321 */
322function get_dirs($basedir, $indent, $level)
323{
324  $fs_dirs = array();
325  $dirs = "";
326
327  if ($opendir = opendir($basedir))
328  {
329    while ($file = readdir($opendir))
330    {
331      if ($file != '.'
332          and $file != '..'
333          and $file != '.svn'
334          and $file != 'thumbnail'
335          and $file != 'pwg_high'
336          and $file != 'pwg_representative'
337          and is_dir ($basedir.'/'.$file))
338      {
339        array_push($fs_dirs, $file);
340        if (!preg_match('/^[a-zA-Z0-9-_.]+$/', $file))
341        {
342          echo 'PWG-WARNING-1: "'.$file.'" : ';
343          echo 'The name of the directory should be composed of ';
344          echo 'letters, figures, "-", "_" or "." ONLY';
345          echo "\n";
346        }
347      }
348    }
349  }
350  // write of the dirs
351  foreach ($fs_dirs as $fs_dir)
352  {
353    $dirs.= "\n".$indent.'<dir'.$level.' name="'.$fs_dir.'">';
354    $dirs.= get_pictures($basedir.'/'.$fs_dir, $indent.'  ');
355    $dirs.= get_dirs($basedir.'/'.$fs_dir, $indent.'  ', $level + 1);
356    $dirs.= "\n".$indent.'</dir'.$level.'>';
357  }
358  return $dirs;
359}
360
361// get_extension returns the part of the string after the last "."
362function get_extension($filename)
363{
364  return substr(strrchr($filename, '.'), 1, strlen ($filename));
365}
366
367// get_filename_wo_extension returns the part of the string before the last
368// ".".
369// get_filename_wo_extension('test.tar.gz') -> 'test.tar'
370function get_filename_wo_extension($filename)
371{
372  return substr($filename, 0, strrpos($filename, '.'));
373}
374
375function get_pictures($dir, $indent)
376{
377  global $conf, $page;
378
379  // fs means FileSystem : $fs_files contains files in the filesystem found
380  // in $dir that can be managed by PhpWebGallery (see get_pwg_files
381  // function), $fs_thumbnails contains thumbnails, $fs_representatives
382  // contains potentially representative pictures for non picture files
383  $fs_files = get_pwg_files($dir);
384  $fs_thumbnails = get_thumb_files($dir);
385  $fs_representatives = get_representative_files($dir);
386  $fs_highs = get_high_files($dir);
387
388  $elements = array();
389
390  $print_dir = preg_replace('/^\.\//', '', $dir);
391  $print_dir = preg_replace('/\/*$/', '/', $print_dir);
392
393  foreach ($fs_files as $fs_file)
394  {
395    $element = array();
396    $element['file'] = $fs_file;
397    $element['path'] = $page['url'].$print_dir.$fs_file;
398    $element['filesize'] = floor(filesize($dir.'/'.$fs_file) / 1024);
399
400    $file_wo_ext = get_filename_wo_extension($fs_file);
401
402    foreach ($conf['picture_ext'] as $ext)
403    {
404      $test = $conf['prefix_thumbnail'].$file_wo_ext.'.'.$ext;
405      if (!in_array($test, $fs_thumbnails))
406      {
407        continue;
408      }
409      else
410      {
411        $element['tn_ext'] = $ext;
412        break;
413      }
414    }
415
416    // 2 cases : the element is a picture or not. Indeed, for a picture
417    // thumbnail is mandatory, high is optional and for non picture element,
418    // thumbnail and representative is optionnal
419    if (in_array(get_extension($fs_file), $conf['picture_ext']))
420    {
421      // if we found a thumnbnail corresponding to our picture...
422      if (isset($element['tn_ext']))
423      {
424        if ($image_size = @getimagesize($dir.'/'.$fs_file))
425        {
426          $element['width'] = $image_size[0];
427          $element['height'] = $image_size[1];
428        }
429
430        if ( in_array($fs_file, $fs_highs) )
431        {
432          $element['has_high'] = 'true';
433        }
434
435        if ($conf['use_exif'])
436        {
437          if ($exif = @read_exif_data($dir.'/'.$fs_file))
438          {
439            foreach ($conf['use_exif_mapping'] as $pwg_key => $exif_key )
440            {
441              if (isset($exif[$exif_key]))
442              {
443                if ( in_array($pwg_key, array('date_creation','date_available') ) )
444                {
445                   if (preg_match('/^(\d{4}):(\d{2}):(\d{2})/'
446                         ,$exif[$exif_key]
447                         ,$matches))
448                   {
449                     $element[$pwg_key] =
450                        $matches[1].'-'.$matches[2].'-'.$matches[3];
451                   }
452                }
453                else
454                {
455                  $element[$pwg_key] = $exif[$exif_key];
456                }
457              }
458            }
459          }
460        }
461
462        if ($conf['use_iptc'])
463        {
464          $iptc = get_sync_iptc_data($dir.'/'.$fs_file);
465          if (count($iptc) > 0)
466          {
467            foreach (array_keys($iptc) as $key)
468            {
469              $element[$key] = $iptc[$key];
470            }
471          }
472        }
473
474        array_push($elements, $element);
475      }
476      else
477      {
478        echo 'PWG-ERROR-1: The thumbnail is missing for '.$dir.'/'.$fs_file;
479        echo '-> '.$dir.'/thumbnail/';
480        echo $conf['prefix_thumbnail'].$file_wo_ext.'.xxx';
481        echo ' ("xxx" can be : ';
482        echo implode(', ', $conf['picture_ext']);
483        echo ')'."\n";
484      }
485    }
486    else
487    {
488      foreach ($conf['picture_ext'] as $ext)
489      {
490        $candidate = $file_wo_ext.'.'.$ext;
491        if (!in_array($candidate, $fs_representatives))
492        {
493          continue;
494        }
495        else
496        {
497          $element['representative_ext'] = $ext;
498          break;
499        }
500      }
501
502      array_push($elements, $element);
503    }
504  }
505
506  $xml = "\n".$indent.'<root>';
507  $attributes = array('file','tn_ext','representative_ext','filesize',
508                      'width','height','date_creation','author','keywords',
509                      'name','comment','has_high', 'path');
510  foreach ($elements as $element)
511  {
512    $xml.= "\n".$indent.'  ';
513    $xml.= '<element';
514    foreach ($attributes as $attribute)
515    {
516      if (isset($element{$attribute}))
517      {
518        $xml.= ' '.$attribute.'="'.$element{$attribute}.'"';
519      }
520    }
521    $xml.= ' />';
522  }
523  $xml.= "\n".$indent.'</root>';
524
525  return $xml;
526}
527
528// +-----------------------------------------------------------------------+
529// |                                script                                 |
530// +-----------------------------------------------------------------------+
531if (isset($_GET['action']))
532{
533  $page['action'] = $_GET['action'];
534}
535else
536{
537  $page['action'] = '';
538}
539
540echo '<pre>';
541switch ($page['action'])
542{
543  case 'generate' :
544  {
545    $start = get_moment();
546
547    $listing = '<informations';
548    $listing.= ' generation_date="'.date('Y-m-d').'"';
549    $listing.= ' phpwg_version="'.htmlentities($conf{'version'}).'"';
550
551    $attrs=array();
552    if ($conf['use_iptc'])
553    {
554      $attrs = array_merge($attrs, array_keys($conf['use_iptc_mapping']) );
555    }
556    if ($conf['use_exif'])
557    {
558      $attrs = array_merge($attrs, array_keys($conf['use_exif_mapping']) );
559    }
560    $listing.= ' metadata="'.implode(',',array_unique($attrs)).'"';
561
562    $end = strrpos($_SERVER['PHP_SELF'], '/') + 1;
563    $local_folder = substr($_SERVER['PHP_SELF'], 0, $end);
564    $page['url'] = 'http://'.$_SERVER['HTTP_HOST'].$local_folder;
565
566    $listing.= ' url="'.$page['url'].'"';
567    $listing.= '/>'."\n";
568
569    $listing.= get_dirs('.', '', 0);
570
571    if ($fp = @fopen("./listing.xml","w"))
572    {
573      fwrite($fp, $listing);
574      fclose($fp);
575      echo 'PWG-INFO-1: listing.xml created in ';
576      echo get_elapsed_time($start, get_moment());
577      echo "\n";
578    }
579    else
580    {
581      echo "PWG-ERROR-2: I can't write the file listing.xml"."\n";
582    }
583    break;
584  }
585  case 'test' :
586  {
587    if (isset($_GET['version']))
588    {
589      if ($_GET['version'] != $conf['version'])
590      {
591        echo 'PWG-ERROR-4: PhpWebGallery versions differs'."\n";
592      }
593      else
594      {
595        echo 'PWG-INFO-2: test successful'."\n";
596      }
597    }
598    else
599    {
600      echo 'PWG-INFO-2: test successful'."\n";
601    }
602    break;
603  }
604  case 'clean' :
605  {
606    if( @unlink('./listing.xml'))
607    {
608      echo 'PWG-INFO-3 : listing.xml file deleted'."\n";
609    }
610    else
611    {
612      echo 'PWG-ERROR-3 : listing.xml does not exist'."\n";
613    }
614    break;
615  }
616  default :
617  {
618    // Menu de lancement pour la mise à jour manuel des sites distant
619    echo '</pre>
620<ul>
621  <li>
622    <a href="create_listing_file.php?action=generate">Generate listing.xml</a>
623  </li>
624
625  <li>
626    <a href="create_listing_file.php?action=test">Test</a>
627  </li>
628
629  <li>
630    <a href="create_listing_file.php?action=clean">Clean</a>
631  </li>
632</ul>
633<pre>';
634  }
635}
636echo '</pre>';
637?>
Note: See TracBrowser for help on using the repository browser.