source: trunk/tools/create_listing_file.php @ 606

Last change on this file since 606 was 606, checked in by plg, 19 years ago
  • images.path column added to reduce database access
  • function mass_inserts moved from admin/remote_sites.php to admin/include/function.php
  • function mass_inserts used in admin/update.php
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.3 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-2004 PhpWebGallery Team - http://phpwebgallery.net |
6// +-----------------------------------------------------------------------+
7// | branch        : BSF (Best So Far)
8// | file          : $RCSfile$
9// | last update   : $Date: 2004-11-16 23:38:34 +0000 (Tue, 16 Nov 2004) $
10// | last modifier : $Author: plg $
11// | revision      : $Revision: 606 $
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'] = 'BSF';
46
47// $conf['use_exif'] set to true if you want to use Exif Date as "creation
48// date" for the element, otherwise, set to false
49$conf['use_exif'] = true;
50
51// $conf['use_iptc'] set to true if you want to use IPTC informations of the
52// element according to get_sync_iptc_data function mapping, otherwise, set
53// to false
54$conf['use_iptc'] = false;
55
56// +-----------------------------------------------------------------------+
57// |                               functions                               |
58// +-----------------------------------------------------------------------+
59
60/**
61 * returns informations from IPTC metadata, mapping is done at the beginning
62 * of the function
63 *
64 * @param string $filename
65 * @return array
66 */
67function get_iptc_data($filename, $map)
68{
69  $result = array();
70 
71  // Read IPTC data
72  $iptc = array();
73 
74  $imginfo = array();
75  getimagesize($filename, $imginfo);
76 
77  if (isset($imginfo['APP13']))
78  {
79    $iptc = iptcparse($imginfo['APP13']);
80    if (is_array($iptc))
81    {
82      $rmap = array_flip($map);
83      foreach (array_keys($rmap) as $iptc_key)
84      {
85        if (isset($iptc[$iptc_key][0]) and $value = $iptc[$iptc_key][0])
86        {
87          // strip leading zeros (weird Kodak Scanner software)
88          while ($value[0] == chr(0))
89          {
90            $value = substr($value, 1);
91          }
92          // remove binary nulls
93          $value = str_replace(chr(0x00), ' ', $value);
94         
95          foreach (array_keys($map, $iptc_key) as $pwg_key)
96          {
97            $result[$pwg_key] = $value;
98          }
99        }
100      }
101    }
102  }
103  return $result;
104}
105
106function get_sync_iptc_data($file)
107{
108  $map = array(
109    'keywords'        => '2#025',
110    'date_creation'   => '2#055',
111    'author'          => '2#122',
112    'name'            => '2#085',
113    'comment'         => '2#120'
114    );
115  $datefields = array('date_creation', 'date_available');
116 
117  $iptc = get_iptc_data($file, $map);
118
119  foreach ($iptc as $pwg_key => $value)
120  {
121    if (in_array($pwg_key, $datefields))
122    {
123      if ( preg_match('/(\d{4})(\d{2})(\d{2})/', $value, $matches))
124      {
125        $iptc[$pwg_key] = $matches[1].'-'.$matches[2].'-'.$matches[3];
126      }
127    }
128  }
129
130  if (isset($iptc['keywords']))
131  {
132    // keywords separator is the comma, nothing else. Allowed characters in
133    // keywords : [A-Za-z0-9], "-" and "_". All other characters will be
134    // considered as separators
135    $iptc['keywords'] = preg_replace('/[^\w-]+/', ',', $iptc['keywords']);
136    $iptc['keywords'] = preg_replace('/^,+|,+$/', '', $iptc['keywords']);
137  }
138
139  return $iptc;
140}
141
142/**
143 * returns a float value coresponding to the number of seconds since the
144 * unix epoch (1st January 1970) and the microseconds are precised :
145 * e.g. 1052343429.89276600
146 *
147 * @return float
148 */
149function get_moment()
150{
151  $t1 = explode(' ', microtime());
152  $t2 = explode('.', $t1[0]);
153  $t2 = $t1[1].'.'.$t2[1];
154  return $t2;
155}
156
157/**
158 * returns the number of seconds (with 3 decimals precision) between the
159 * start time and the end time given.
160 *
161 * @param float start
162 * @param float end
163 * @return void
164 */
165function get_elapsed_time($start, $end)
166{
167  return number_format($end - $start, 3, '.', ' ').' s';
168}
169
170/**
171 * returns an array with all picture files according to $conf['file_ext']
172 *
173 * @param string $dir
174 * @return array
175 */
176function get_pwg_files($dir)
177{
178  global $conf;
179
180  $pictures = array();
181  if ($opendir = opendir($dir))
182  {
183    while ($file = readdir($opendir))
184    {
185      if (in_array(get_extension($file), $conf['file_ext']))
186      {
187        array_push($pictures, $file);
188        if (!preg_match('/^[a-zA-Z0-9-_.]+$/', $file))
189        {
190          echo 'PWG-WARNING-2: "'.$file.'" : ';
191          echo 'The name of the file should be composed of ';
192          echo 'letters, figures, "-", "_" or "." ONLY';
193          echo "\n";
194        }
195      }
196    }
197  }
198  return $pictures;
199}
200
201/**
202 * returns an array with all thumbnails according to $conf['picture_ext']
203 * and $conf['prefix_thumbnail']
204 *
205 * @param string $dir
206 * @return array
207 */
208function get_thumb_files($dir)
209{
210  global $conf;
211
212  $prefix_length = strlen($conf['prefix_thumbnail']);
213 
214  $thumbnails = array();
215  if ($opendir = @opendir($dir.'/thumbnail'))
216  {
217    while ($file = readdir($opendir))
218    {
219      if (in_array(get_extension($file), $conf['picture_ext'])
220          and substr($file,0,$prefix_length) == $conf['prefix_thumbnail'])
221      {
222        array_push($thumbnails, $file);
223      }
224    }
225  }
226  return $thumbnails;
227}
228
229/**
230 * returns an array with representative picture files of a directory
231 * according to $conf['picture_ext']
232 *
233 * @param string $dir
234 * @return array
235 */
236function get_representative_files($dir)
237{
238  global $conf;
239
240  $pictures = array();
241  if ($opendir = @opendir($dir.'/pwg_representative'))
242  {
243    while ($file = readdir($opendir))
244    {
245      if (in_array(get_extension($file), $conf['picture_ext']))
246      {
247        array_push($pictures, $file);
248      }
249    }
250  }
251  return $pictures;
252}
253
254/**
255 * search in $basedir the sub-directories and calls get_pictures
256 *
257 * @return void
258 */
259function get_dirs($basedir, $indent, $level)
260{
261  $fs_dirs = array();
262  $dirs = "";
263
264  if ($opendir = opendir($basedir))
265  {
266    while ($file = readdir($opendir))
267    {
268      if ($file != '.'
269          and $file != '..'
270          and $file != 'thumbnail'
271          and $file != 'pwg_high'
272          and $file != 'pwg_representative'
273          and is_dir ($basedir.'/'.$file))
274      {
275        array_push($fs_dirs, $file);
276        if (!preg_match('/^[a-zA-Z0-9-_.]+$/', $file))
277        {
278          echo 'PWG-WARNING-1: "'.$file.'" : ';
279          echo 'The name of the directory should be composed of ';
280          echo 'letters, figures, "-", "_" or "." ONLY';
281          echo "\n";
282        }
283      }
284    }
285  }
286  // write of the dirs
287  foreach ($fs_dirs as $fs_dir)
288  {
289    $dirs.= "\n".$indent.'<dir'.$level.' name="'.$fs_dir.'">';
290    $dirs.= get_pictures($basedir.'/'.$fs_dir, $indent.'  ');
291    $dirs.= get_dirs($basedir.'/'.$fs_dir, $indent.'  ', $level + 1);
292    $dirs.= "\n".$indent.'</dir'.$level.'>';
293  }
294  return $dirs;         
295}
296
297// get_extension returns the part of the string after the last "."
298function get_extension($filename)
299{
300  return substr(strrchr($filename, '.'), 1, strlen ($filename));
301}
302
303// get_filename_wo_extension returns the part of the string before the last
304// ".".
305// get_filename_wo_extension('test.tar.gz') -> 'test.tar'
306function get_filename_wo_extension($filename)
307{
308  return substr($filename, 0, strrpos($filename, '.'));
309}
310
311function get_pictures($dir, $indent)
312{
313  global $conf, $page;
314 
315  // fs means FileSystem : $fs_files contains files in the filesystem found
316  // in $dir that can be managed by PhpWebGallery (see get_pwg_files
317  // function), $fs_thumbnails contains thumbnails, $fs_representatives
318  // contains potentially representative pictures for non picture files
319  $fs_files = get_pwg_files($dir);
320  $fs_thumbnails = get_thumb_files($dir);
321  $fs_representatives = get_representative_files($dir);
322
323  $elements = array();
324
325  $print_dir = preg_replace('/^\.\//', '', $dir);
326  $print_dir = preg_replace('/\/*$/', '/', $print_dir);
327 
328  foreach ($fs_files as $fs_file)
329  {
330    $element = array();
331    $element['file'] = $fs_file;
332    $element['path'] = $page['url'].$print_dir.$fs_file;
333    $element['filesize'] = floor(filesize($dir.'/'.$fs_file) / 1024);
334   
335    $file_wo_ext = get_filename_wo_extension($fs_file);
336
337    foreach ($conf['picture_ext'] as $ext)
338    {
339      $test = $conf['prefix_thumbnail'].$file_wo_ext.'.'.$ext;
340      if (!in_array($test, $fs_thumbnails))
341      {
342        continue;
343      }
344      else
345      {
346        $element['tn_ext'] = $ext;
347        break;
348      }
349    }
350
351    // 2 cases : the element is a picture or not. Indeed, for a picture
352    // thumbnail is mandatory and for non picture element, thumbnail and
353    // representative is optionnal
354    if (in_array(get_extension($fs_file), $conf['picture_ext']))
355    {
356      // if we found a thumnbnail corresponding to our picture...
357      if (isset($element['tn_ext']))
358      {
359        if ($image_size = @getimagesize($dir.'/'.$fs_file))
360        {
361          $element['width'] = $image_size[0];
362          $element['height'] = $image_size[1];
363        }
364
365        if ($conf['use_exif'])
366        {
367          if ($exif = @read_exif_data($dir.'/'.$fs_file))
368          {
369            if (isset($exif['DateTime']))
370            {
371              preg_match('/^(\d{4}):(\d{2}):(\d{2})/'
372                         ,$exif['DateTime']
373                         ,$matches);
374              $element['date_creation'] =
375                $matches[1].'-'.$matches[2].'-'.$matches[3];
376            }
377          }
378        }
379
380        if ($conf['use_iptc'])
381        {
382          $iptc = get_sync_iptc_data($dir.'/'.$fs_file);
383          if (count($iptc) > 0)
384          {
385            foreach (array_keys($iptc) as $key)
386            {
387              $element[$key] = addslashes($iptc[$key]);
388            }
389          }
390        }
391       
392        array_push($elements, $element);
393      }
394      else
395      {
396        echo 'PWG-ERROR-1: The thumbnail is missing for '.$dir.'/'.$fs_file;
397        echo '-> '.$dir.'/thumbnail/';
398        echo $conf['prefix_thumbnail'].$file_wo_ext.'.xxx';
399        echo ' ("xxx" can be : ';
400        echo implode(', ', $conf['picture_ext']);
401        echo ')'."\n";
402      }
403    }
404    else
405    {
406      foreach ($conf['picture_ext'] as $ext)
407      {
408        $candidate = $file_wo_ext.'.'.$ext;
409        if (!in_array($candidate, $fs_representatives))
410        {
411          continue;
412        }
413        else
414        {
415          $element['representative_ext'] = $ext;
416          break;
417        }
418      }
419     
420      array_push($elements, $element);
421    }
422  }
423
424  $xml = "\n".$indent.'<root>';
425  $attributes = array('file','tn_ext','representative_ext','filesize',
426                      'width','height','date_creation','author','keywords',
427                      'name','comment','path');
428  foreach ($elements as $element)
429  {
430    $xml.= "\n".$indent.'  ';
431    $xml.= '<element';
432    foreach ($attributes as $attribute)
433    {
434      if (isset($element{$attribute}))
435      {
436        $xml.= ' '.$attribute.'="'.$element{$attribute}.'"';
437      }
438    }
439    $xml.= ' />';
440  }
441  $xml.= "\n".$indent.'</root>';
442
443  return $xml;
444}
445
446// +-----------------------------------------------------------------------+
447// |                                script                                 |
448// +-----------------------------------------------------------------------+
449if (isset($_GET['action']))
450{
451  $page['action'] = $_GET['action'];
452}
453else
454{
455  $page['action'] = 'generate';
456}
457echo '<pre>';
458switch ($page['action'])
459{
460  case 'generate' :
461  {
462    $start = get_moment();
463   
464    $listing = '<informations';
465    $listing.= ' generation_date="'.date('Y-m-d').'"';
466    $listing.= ' phpwg_version="'.$conf{'version'}.'"';
467   
468    $end = strrpos($_SERVER['PHP_SELF'], '/') + 1;
469    $local_folder = substr($_SERVER['PHP_SELF'], 0, $end);
470    $page['url'] = 'http://'.$_SERVER['HTTP_HOST'].$local_folder;
471   
472    $listing.= ' url="'.$page['url'].'"';
473    $listing.= '/>'."\n";
474   
475    $listing.= get_dirs('.', '', 0);
476   
477    if ($fp = @fopen("./listing.xml","w"))
478    {
479      fwrite($fp, $listing);
480      fclose($fp);
481      echo 'PWG-INFO-1: listing.xml created in ';
482      echo get_elapsed_time($start, get_moment());
483      echo "\n";
484    }
485    else
486    {
487      echo "PWG-ERROR-2: I can't write the file listing.xml"."\n";
488    }
489    break;
490  }
491  case 'test' :
492  {
493    if (isset($_GET['version']))
494    {
495      if ($_GET['version'] != $conf['version'])
496      {
497        echo 'PWG-ERROR-4: PhpWebGallery versions differs'."\n";
498      }
499      else
500      {
501        echo 'PWG-INFO-2: test successful'."\n";
502      }
503    }
504    else
505    {
506      echo 'PWG-INFO-2: test successful'."\n";
507    }
508    break;
509  }
510  case 'clean' :
511  {
512    if( @unlink('./listing.xml'))
513    {
514      echo 'PWG-INFO-3 : listing.xml file deleted'."\n";
515    }
516    else
517    {
518      echo 'PWG-ERROR-3 : listing.xml does not exist'."\n";
519    }
520    break;
521  }
522}
523echo '</pre>';
524?>
Note: See TracBrowser for help on using the repository browser.