source: tags/build-A01/tools/create_listing_file.php @ 11761

Last change on this file since 11761 was 1635, checked in by rub, 18 years ago

Fixed Issue ID 0000593: *.jpeg support in PWG

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