Delegate all exiftool commands to PHPExiftool

This commit is contained in:
Romain Neutron
2012-05-04 20:17:17 +02:00
parent 26a823dcc2
commit 135420008b
17 changed files with 372 additions and 458 deletions

View File

@@ -40,45 +40,32 @@ class Tools implements ControllerProviderInterface
$selection = $helper->get_elements(); $selection = $helper->get_elements();
$binary = __DIR__ . '/../../../../../vendor/phpexiftool/exiftool/exiftool';
$metadatas = false; $metadatas = false;
$record = null; $record = null;
$metadatasFirst = $metadatasSecond = array();
if (count($selection) == 1 && ! empty($binary)) { if (count($selection) == 1) {
try { try {
$record = reset($selection);
$file = $record->get_subdef('document')->get_pathfile();
$cmd = $binary . ' -h ' . escapeshellarg($file);
$out = ""; $record = reset($selection);
exec($cmd, $out);
foreach ($out as $liout) { $reader = new \PHPExiftool\Reader();
if (strpos($liout, '<tr><td>Directory') === false) $metadatas = $reader->files($record->get_subdef('document')->get_pathfile())
$metadatasFirst[] = $liout; ->first()->getMetadatas();
}
$out = ""; } catch (\PHPExiftool\Exception\Exception $e) {
$cmd = $binary . ' -X -n -fast ' . escapeshellarg($file) . '';
exec($cmd, $out);
foreach ($out as $liout) {
$metadatasSecond[] = htmlentities($liout);
}
$metadatas = true;
} catch (\Exception $e) {
} }
} }
$reader = null;
$template = 'prod/actions/Tools/index.html.twig'; $template = 'prod/actions/Tools/index.html.twig';
$var = array( $var = array(
'helper' => $helper, 'helper' => $helper,
'selection' => $selection, 'selection' => $selection,
'record' => $record, 'record' => $record,
'metadatas' => $metadatas, 'metadatas' => $metadatas,
'metadatasFirst' => $metadatasFirst,
'metadatasSecond' => $metadatasSecond
); );
return new Response($app['Core']->getTwig()->render($template, $var)); return new Response($app['Core']->getTwig()->render($template, $var));

View File

@@ -1,103 +0,0 @@
<?php
class exiftool
{
public static function get_fields($filename, $fields)
{
$system = system_server::get_platform();
$registry = registry::get_instance();
$ret = array();
if (in_array($system, array('DARWIN', 'LINUX'))) {
$cmd = __DIR__ . '/../../vendor/phpexiftool/exiftool/exiftool '
. escapeshellarg($filename) ;
} else {
if (chdir($registry->get('GV_RootPath') . 'tmp/')) {
$cmd = 'start /B /LOW ' . __DIR__ . '/../../vendor/phpexiftool/exiftool/exiftool.exe '
. escapeshellarg($filename) . '';
}
}
if ($cmd) {
$s = @shell_exec($cmd);
if (trim($s) != '') {
$lines = explode("\n", $s);
foreach ($lines as $line) {
$cells = explode(':', $line);
if (count($cells) < 2)
continue;
$cell_1 = trim(array_shift($cells));
$cell_2 = trim(implode(':', $cells));
if (in_array($cell_1, $fields))
$ret[$cell_1] = $cell_2;
}
}
}
foreach ($fields as $field) {
if ( ! isset($ret[$field]))
$ret[$field] = false;
}
return $ret;
}
const EXTRACT_XML_RDF = 0;
const EXTRACT_TEXT = 1;
protected static $extracts = array();
public static function extract_metadatas(system_file $file, $extract_type = null)
{
if (isset(self::$extracts[$file->getPathname()]) && isset(self::$extracts[$file->getPathname()][$extract_type])) {
return self::$extracts[$file->getPathname()][$extract_type];
}
$registry = registry::get_instance();
$system = system_server::get_platform();
$options = '';
switch ($extract_type) {
case self::EXTRACT_TEXT:
default:
break;
case self::EXTRACT_XML_RDF:
$options .= ' -X -n -fast ';
break;
}
if (in_array($system, array('DARWIN', 'LINUX'))) {
$cmd = __DIR__ . '/../../vendor/phpexiftool/exiftool/exiftool '
. $options . escapeshellarg($file->getPathname()) . '';
} else {
if (chdir($registry->get('GV_RootPath') . 'tmp/')) {
$cmd = 'start /B /LOW ' . __DIR__ . '/../../vendor/phpexiftool/exiftool/exiftool.exe'
. ' ' . $options . escapeshellarg($file->getPathname()) . '';
}
}
$s = shell_exec($cmd);
if ($s) {
self::$extracts[$file->getPathname()][$extract_type] = $s;
}
return self::$extracts[$file->getPathname()][$extract_type];
}
public static function flush_extracts(system_file $file)
{
if (isset(self::$extracts[$file->getPathname()]))
unset(self::$extracts[$file->getPathname()]);
return;
}
}

View File

@@ -128,63 +128,64 @@ class p4file
public static function check_file_error($filename, $sbas_id, $originalname) public static function check_file_error($filename, $sbas_id, $originalname)
{ {
$registry = registry::get_instance(); $checks = array();
$system_file = new system_file($filename); $system_file = new system_file($filename);
$doctype = $system_file->get_phrasea_type(); $doctype = $system_file->get_phrasea_type();
$databox = databox::get_instance($sbas_id); $databox = databox::get_instance($sbas_id);
if ($baseprefs = $databox->get_sxml_structure()) {
$file_checks = $baseprefs->filechecks;
}
else
throw new Exception(_('prod::erreur : impossible de lire les preferences de base'));
if ($baseprefs = $databox->get_sxml_structure()) {
$file_checks = $baseprefs->filechecks;
$checks = $file_checks->$doctype;
$checks = $checks[0];
} else {
throw new Exception(_('prod::erreur : impossible de lire les preferences de base'));
}
$errors = array(); $errors = array();
$datas = exiftool::get_fields($filename, array('Color Space Data', 'Color Space', 'Color Mode', 'Image Width', 'Image Height')); $media = \MediaVorus\MediaVorus::guess($filename);
if ($checks = $file_checks->$doctype) { $width = $height = 0;
foreach ($checks[0] as $name => $value) { $colorSpace = null;
switch ($name) {
case 'name':
$records = record_adapter::get_records_by_originalname($databox, $original_name, 0, 1);
if (count($records) > 0)
$errors[] = sprintf(_('Le fichier \'%s\' existe deja'), $originalname);
break;
case 'size':
$min = min($datas['Image Height'], $datas['Image Width']);
if ($min < (int) $value) {
$errors[] = sprintf(_('Taille trop petite : %dpx'), $min);
}
break;
case 'color_space':
$required = in_array($value, array('sRGB', 'RGB')) ? 'RGB' : $value;
$go = false;
$results = array($datas['Color Space'], $datas['Color Space Data'], $datas['Color Mode']); if ($media instanceof \MediaVorus\Media\Image) {
$width = $media->getWidth();
$height = $media->getHeight();
$colorSpace = strtolower($media->getColorSpace());
}
$results_str = implode(' ', $results); foreach ($checks as $name => $value) {
switch ($name) {
case 'name':
$records = record_adapter::get_records_by_originalname($databox, $original_name, 0, 1);
if (count($records) > 0)
$errors[] = sprintf(_('Le fichier \'%s\' existe deja'), $originalname);
break;
case 'size':
if (min($width, $height) < (int) $value) {
$errors[] = sprintf(_('Taille trop petite : %dpx'), $min);
}
break;
case 'color_space':
$required = strtolower(in_array($value, array('sRGB', 'RGB')) ? 'RGB' : $value);
if (trim($results_str) === '') { $go = false;
$go = true;
} else {
if ($required == 'RGB' && count(array_intersect($results, array('sRGB', 'RGB'))) > 0) {
$go = true;
} elseif (in_array($required, $results)) {
$go = true;
}
}
if ( ! $colorSpace || $required == $colorSpace) {
$go = true;
} else if ($required == 'rgb' && in_array($colorSpace, array('srgb', 'rgb')) > 0) {
$go = true;
}
if ( ! $go) { if ( ! $go) {
$errors[] = sprintf(_('Mauvais mode colorimetrique : %s'), $results_str); $errors[] = sprintf(_('Mauvais mode colorimetrique : %s'), $colorSpace);
} }
break; break;
}
} }
} }

View File

@@ -239,16 +239,13 @@ class setup
public static function discover_binaries() public static function discover_binaries()
{ {
if (system_server::get_platform() == 'WINDOWS') { if (system_server::get_platform() == 'WINDOWS') {
$exiftool = dirname(__DIR__) . '/vendor/exiftool/exiftool.exe';
$indexer = dirname(dirname(__DIR__)) . '/bin/phraseanet_indexer.exe'; $indexer = dirname(dirname(__DIR__)) . '/bin/phraseanet_indexer.exe';
} else { } else {
$exiftool = dirname(__DIR__) . '/vendor/exiftool/exiftool';
$indexer = null; $indexer = null;
} }
return array( return array(
'php' => array('name' => 'PHP CLI', 'binary' => self::discover_binary('php')), 'php' => array('name' => 'PHP CLI', 'binary' => self::discover_binary('php')),
'exiftool' => array('name' => 'Exiftool', 'binary' => self::discover_binary('exiftool', array($exiftool))),
'phraseanet_indexer' => array('name' => 'Indexeur Phrasea', 'binary' => self::discover_binary('phraseanet_indexer', array($indexer))), 'phraseanet_indexer' => array('name' => 'Indexeur Phrasea', 'binary' => self::discover_binary('phraseanet_indexer', array($indexer))),
'convert' => array('name' => 'ImageMagick (convert)', 'binary' => self::discover_binary('convert')), 'convert' => array('name' => 'ImageMagick (convert)', 'binary' => self::discover_binary('convert')),
'composite' => array('name' => 'ImageMagick (composite)', 'binary' => self::discover_binary('composite')), 'composite' => array('name' => 'ImageMagick (composite)', 'binary' => self::discover_binary('composite')),
@@ -259,7 +256,6 @@ class setup
'MP4Box' => array('name' => 'MP4Box', 'binary' => self::discover_binary('MP4Box')), 'MP4Box' => array('name' => 'MP4Box', 'binary' => self::discover_binary('MP4Box')),
'xpdf' => array('name' => 'XPDF', 'binary' => self::discover_binary('xpdf')), 'xpdf' => array('name' => 'XPDF', 'binary' => self::discover_binary('xpdf')),
'ffmpeg' => array('name' => 'FFmpeg', 'binary' => self::discover_binary('ffmpeg')), 'ffmpeg' => array('name' => 'FFmpeg', 'binary' => self::discover_binary('ffmpeg')),
'mplayer' => array('name' => 'MPlayer', 'binary' => self::discover_binary('mplayer'))
); );
} }

View File

@@ -9,6 +9,10 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
use PHPExiftool\Driver\Metadata;
use PHPExiftool\Driver\Tag;
use PHPExiftool\Driver\Value;
/** /**
* *
* *
@@ -459,15 +463,25 @@ class system_file extends \SplFileInfo
return $this->uuid; return $this->uuid;
} }
$datas = exiftool::extract_metadatas($this, exiftool::EXTRACT_XML_RDF); $reader = new PHPExiftool\Reader();
$domrdf = new DOMDocument(); $metadatas = $reader->files($this->getPathname())->first()->getMetadatas();
$domrdf->recover = true;
$domrdf->preserveWhiteSpace = false;
if ($domrdf->loadXML($datas)) { $uniqueKeys = array('XMP-exif:ImageUniqueID', 'IPTC:UniqueDocumentID');
$this->uuid = $this->test_rdf_fields($domrdf);
foreach ($uniqueKeys as $uniqueKey) {
if ($metadatas->containsKey($uniqueKey)) {
$value = (string) $metadatas->get($uniqueKey)->getValue()->getValue();
if (uuid::is_valid($value)) {
$this->uuid = $value;
break;
}
}
} }
$reader = null;
return $this->uuid; return $this->uuid;
} }
@@ -513,64 +527,37 @@ class system_file extends \SplFileInfo
public function write() public function write()
{ {
$system = system_server::get_platform(); $metadatas = new Metadata\MetadataBag();
$registry = registry::get_instance(); $metadatas->add(
new Metadata\Metadata(
if (in_array($system, array('DARWIN', 'LINUX'))) { new Tag\IPTC\UniqueDocumentID(),
new Value\Mono($this->uuid)
$cmd = __DIR__ . '/../../../vendor/phpexiftool/exiftool/exiftool' )
. ' -m -overwrite_original ' );
. ' -XMP-exif:ImageUniqueID=\'' . $this->uuid . '\'' $metadatas->add(
. ' -IPTC:UniqueDocumentID=\'' . $this->uuid . '\'' new Metadata\Metadata(
. ' ' . escapeshellarg($this->getPathname()); new Tag\ExifIFD\ImageUniqueID(),
} else { new Value\Mono($this->uuid)
if (chdir($registry->get('GV_RootPath') . 'tmp/')) { )
);
$cmd = 'start /B /LOW ' . __DIR__ . '/../../../vendor/phpexiftool/exiftool/exiftool.exe' $metadatas->add(
. ' -m -overwrite_original' new Metadata\Metadata(
. ' -XMP-exif:ImageUniqueID=\'' . $this->uuid . '\'' new Tag\XMPExif\ImageUniqueID(),
. ' -IPTC:UniqueDocumentID=\'' . $this->uuid . '\'' new Value\Mono($this->uuid)
. ' ' . escapeshellarg($this->getPathname()); )
}
}
if ($cmd) {
$s = @shell_exec($cmd);
}
return $this;
}
private function test_rdf_fields($rdf_dom)
{
$xptrdf = new DOMXPath($rdf_dom);
$xptrdf->registerNamespace('XMP-exif', 'http://ns.exiftool.ca/XMP/XMP-exif/1.0/');
$xptrdf->registerNamespace('IPTC', 'http://ns.exiftool.ca/IPTC/IPTC/1.0/');
$fields = array(
'/rdf:RDF/rdf:Description/XMP-exif:ImageUniqueID',
'/rdf:RDF/rdf:Description/IPTC:UniqueDocumentID'
); );
foreach ($fields as $field) { try {
$x = $xptrdf->query($field);
if ($x->length > 0) { $writer = new PHPExiftool\Writer();
$x = $x->item(0); $writer->write($this->getPathname(), $metadatas);
} catch (PHPExiftool\Exception\Exception $e) {
$encoding = strtolower($x->getAttribute('rdf:datatype') . $x->getAttribute('et:encoding'));
$base64_encoded = (strpos($encoding, 'base64') !== false);
if (($v = $x->firstChild) && $v->nodeType == XML_TEXT_NODE) {
$value = $base64_encoded ? base64_decode($v->nodeValue) : $v->nodeValue;
if (uuid::is_valid($value)) {
return $value;
}
}
}
} }
return false; $writer = $metadatas = null;
return $this;
} }
public static function mkdir($path, $depth = 0) public static function mkdir($path, $depth = 0)
@@ -714,153 +701,70 @@ class system_file extends \SplFileInfo
$tfields[metadata_description_PHRASEANET_pdftext::get_source()] = $this->read_pdf_datas(); $tfields[metadata_description_PHRASEANET_pdftext::get_source()] = $this->read_pdf_datas();
} }
$datas = exiftool::extract_metadatas($this, exiftool::EXTRACT_XML_RDF); $unicode = new unicode();
$domrdf = new DOMDocument();
$domrdf->recover = true;
$domrdf->preserveWhiteSpace = false;
if ($domrdf->loadXML($datas)) { $reader = new PHPExiftool\Reader();
$xptrdf = new DOMXPath($domrdf);
$defined_namespaces = array( $metadatas = $reader->files($this->getPathname())->first()->getMetadatas();
'rdf' => true
, 'XMP-exif' => true
, 'PHRASEANET' => true
);
$xptrdf->registerNamespace('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'); foreach ($meta_struct as $meta) {
$pattern = "(xmlns:([a-zA-Z-_0-9]+)=[']{1}(https?:[/{2,4}|\\{2,4}][\w:#%/;$()~_?/\-=\\\.&]*)[']{1})"; $name = $meta->get_name();
preg_match_all($pattern, $datas, $matches, PREG_PATTERN_ORDER, 0); $src = $meta->get_metadata_source();
$key = $meta->get_metadata_namespace() . ':' . $meta->get_metadata_tagname();
$xptrdf->registerNamespace('XMP-exif', 'http://ns.exiftool.ca/XMP/XMP-exif/1.0/'); if ( ! $src || ! $metadatas->containsKey($key)) {
$xptrdf->registerNamespace('PHRASEANET', 'http://phraseanet.com/metas/PHRASEANET/1.0/'); continue;
foreach ($matches[2] as $key => $value) {
$defined_namespaces[$matches[1][$key]] = true;
$xptrdf->registerNamespace($matches[1][$key], $value);
} }
// tous les champs de la structure
foreach ($meta_struct as $meta) {
if ( ! array_key_exists($meta->get_metadata_namespace(), $defined_namespaces)) { if ( ! isset($tfields[$src])) {
$xptrdf->registerNamespace($meta->get_metadata_namespace(), 'http://ns.exiftool.ca/' . $meta->get_metadata_namespace() . '/1.0/'); $tfields[$src] = array();
$defined_namespaces[$meta->get_metadata_namespace()] = true;
}
$fname = $meta->get_name();
$src = $meta->get_metadata_source();
if ( ! $src)
continue;
$x = $xptrdf->query($src);
if ( ! $x || $x->length != 1) {
continue;
}
if ( ! isset($tfields[$src])) {
$tfields[$src] = array();
}
$x = $x->item(0);
//double check -- exiftool uses et:encoding in version prior 7.71
$encoding = strtolower($x->getAttribute('rdf:datatype') . $x->getAttribute('et:encoding'));
$base64_encoded = (strpos($encoding, 'base64') !== false);
$bag = $xptrdf->query('rdf:Bag', $x);
if ($bag && $bag->length == 1) {
$li = $xptrdf->query('rdf:li', $bag->item(0));
if ($li->length > 0) {
for ($ili = 0; $ili < $li->length; $ili ++ ) {
$value = $base64_encoded ? base64_decode($li->item($ili)->nodeValue) : $li->item($ili)->nodeValue;
$utf8value = trim($this->guessCharset($value));
$tfields[$src][] = $utf8value;
}
}
} else {
if (($v = $x->firstChild) && $v->nodeType == XML_TEXT_NODE) {
$value = $base64_encoded ? base64_decode($v->nodeValue) : $v->nodeValue;
$utf8value = $this->guessCharset($value);
$tfields[$src] = array($utf8value);
}
}
} }
foreach ((array) $metadatas->get($key)->getValue()->getValue() as $value) {
$value = $unicode->substituteCtrlCharacters($value, ' ');
$tfields[$src][] = $unicode->toUTF8($value);
}
$tfields[$src] = array_unique($tfields[$src]);
} }
foreach ($meta_struct as $meta) { foreach ($meta_struct as $meta) {
$fname = $meta->get_name();
$name = $meta->get_name();
$src = $meta->get_metadata_source(); $src = $meta->get_metadata_source();
$typ = mb_strtolower($meta->get_type()); // l'attribut 'type' du champ
$multi = $meta->is_multi(); // l'attribut 'multi' du champ
if (trim($src) === '' || isset($tfields[$src]) === false) if ( ! isset($tfields[$src])) {
continue; continue;
if (trim(implode('', $tfields[$src])) === '')
continue;
// un champ iptc peut etre multi-value, on recoit donc toujours un tableau comme valeur
$tmpval = array();
foreach ($tfields[$src] as $val) {
// on remplace les caracteres de controle (tous < 32 sauf 9,10,13)
$val = $this->kill_ctrlchars($val);
if ($typ == 'date') {
$val = str_replace(array('-', ':', '/', '.'), array(' ', ' ', ' ', ' '), $val);
$ip_date_yyyy = 0;
$ip_date_mm = 0;
$ip_date_dd = 0;
$ip_date_hh = 0;
$ip_date_nn = 0;
$ip_date_ss = 0;
switch (sscanf($val, '%d %d %d %d %d %d', $ip_date_yyyy, $ip_date_mm, $ip_date_dd, $ip_date_hh, $ip_date_nn, $ip_date_ss)) {
case 1:
$val = sprintf('%04d/00/00 00:00:00', $ip_date_yyyy);
break;
case 2:
$val = sprintf('%04d/%02d/00 00:00:00', $ip_date_yyyy, $ip_date_mm);
break;
case 3:
$val = sprintf('%04d/%02d/%02d 00:00:00', $ip_date_yyyy, $ip_date_mm, $ip_date_dd);
break;
case 4:
$val = sprintf('%04d/%02d/%02d %02d:00:00', $ip_date_yyyy, $ip_date_mm, $ip_date_dd, $ip_date_hh);
break;
case 5:
$val = sprintf('%04d/%02d/%02d %02d:%02d:00', $ip_date_yyyy, $ip_date_mm, $ip_date_dd, $ip_date_hh, $ip_date_nn);
break;
case 6:
$val = sprintf('%04d/%02d/%02d %02d:%02d:%02d', $ip_date_yyyy, $ip_date_mm, $ip_date_dd, $ip_date_hh, $ip_date_nn, $ip_date_ss);
break;
default:
$val = '0000/00/00 00:00:00';
}
}
if ( ! in_array($val, $tmpval))
$tmpval[] = $val;
} }
foreach ($tmpval as $val) { foreach ($tfields[$src] as $value) {
$ret = $this->add_meta_value($meta, $ret, $val);
if ($meta->get_type() == 'date') {
$value = $unicode->parseDate($value);
}
if (trim($value) == '') {
continue;
}
$ret = $this->add_meta_value($meta, $ret, $value);
} }
} }
$statBit = null; $statBit = null;
$sxcaption = null; $sxcaption = null;
if ( ! is_null($caption_file)) { if ( ! is_null($caption_file)) {
// on a une description xml en plus a lire dans un fichier externe
if ($domcaption = @DOMDocument::load($caption_file->getPathname())) { if ($domcaption = @DOMDocument::load($caption_file->getPathname())) {
if ($domcaption->documentElement->tagName == 'description') { // il manque 'record' (ca commence par 'description') : on repare
$newdomcaption = new DOMDocument('1.0', 'UTF-8'); $sxcaption = simplexml_load_file($caption_file->getPathname());
$newdomcaption->standalone = true;
$newdomrec = $newdomcaption->appendChild($newdomcaption->createElement('record'));
$newdomrec->appendChild($newdomcaption->importNode($domcaption->documentElement, true));
$sxcaption = simplexml_load_string($newdomcaption->saveXML());
} else {
$sxcaption = simplexml_load_file($caption_file->getPathname());
}
if ($inStatus = $sxcaption->status) { if ($inStatus = $sxcaption->status) {
if ($inStatus && $inStatus != '') { if ($inStatus && $inStatus != '') {
$statBit = $inStatus; $statBit = $inStatus;
@@ -873,6 +777,8 @@ class system_file extends \SplFileInfo
} }
} }
$reader = $unicode = null;
return(array('metadatas' => $ret, 'status' => $statBit)); return(array('metadatas' => $ret, 'status' => $statBit));
} }

View File

@@ -47,14 +47,6 @@ class task_period_upgradetov31 extends task_abstract
$conn = $appbox->get_connection(); $conn = $appbox->get_connection();
$running = true; $running = true;
$binary = __DIR__ . '/../../../../vendor/phpexiftool/exiftool/exiftool';
if ( ! is_executable($binary)) {
printf("Exiftool is not executable, script can not process\n");
return 'stopped';
}
$todo = $this->how_many_left(); $todo = $this->how_many_left();
$done = 0; $done = 0;

View File

@@ -8,6 +8,12 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
use PHPExiftool\Driver\Metadata;
use PHPExiftool\Driver\Value;
use PHPExiftool\Driver\Tag;
use PHPExiftool\Driver\TagFactory;
use PHPExiftool\Writer;
/** /**
* *
* @package task_manager * @package task_manager
@@ -233,40 +239,8 @@ class task_period_writemeta extends task_databoxAbstract
return $rs; return $rs;
} }
protected function format_value($type, $value)
{
if ($type == 'date') {
$value = str_replace(array("-", ":", "/", "."), array(" ", " ", " ", " "), $value);
$ip_date_yyyy = 0;
$ip_date_mm = 0;
$ip_date_dd = 0;
$ip_date_hh = 0;
$ip_date_nn = 0;
$ip_date_ss = 0;
switch (sscanf($value, "%d %d %d %d %d %d", $ip_date_yyyy, $ip_date_mm, $ip_date_dd, $ip_date_hh, $ip_date_nn, $ip_date_ss)) {
case 1:
$value = sprintf("%04d:00:00", $ip_date_yyyy);
break;
case 2:
$value = sprintf("%04d:%02d:00", $ip_date_yyyy, $ip_date_mm);
break;
case 3:
case 4:
case 5:
case 6:
$value = sprintf("%04d:%02d:%02d", $ip_date_yyyy, $ip_date_mm, $ip_date_dd);
break;
default:
$value = '0000:00:00';
}
}
return $value;
}
protected function process_one_content(databox $databox, Array $row) protected function process_one_content(databox $databox, Array $row)
{ {
$coll_id = $row['coll_id'];
$record_id = $row['record_id']; $record_id = $row['record_id'];
$jeton = $row['jeton']; $jeton = $row['jeton'];
@@ -286,73 +260,70 @@ class task_period_writemeta extends task_databoxAbstract
} }
} }
$registry = $databox->get_registry(); $metadatas = new Metadata\MetadataBag();
$fields = $record->get_caption()->get_fields();
$subCMD = '';
if ($record->get_uuid()) { if ($record->get_uuid()) {
$subCMD .= ' -XMP-exif:ImageUniqueID='; $metadatas->add(
$subCMD .= escapeshellarg($record->get_uuid()); new Metadata\Metadata(
$subCMD .= ' -IPTC:UniqueDocumentID='; new Tag\XMPExif\ImageUniqueID(),
$subCMD .= escapeshellarg($record->get_uuid()); new Value\Mono($record->get_uuid())
)
);
$metadatas->add(
new Metadata\Metadata(
new Tag\ExifIFD\ImageUniqueID(),
new Value\Mono($record->get_uuid())
)
);
$metadatas->add(
new Metadata\Metadata(
new Tag\IPTC\UniqueDocumentID(),
new Value\Mono($record->get_uuid())
)
);
} }
foreach ($fields as $field) { foreach ($record->get_caption()->get_fields() as $field) {
$meta = $field->get_databox_field();
$meta = $field->get_databox_field();
/* @var $meta \databox_field */ /* @var $meta \databox_field */
if (trim($meta->get_metadata_source()) === '') { try {
$tag = TagFactory::getFromRDFTagname($meta->get_metadata_source());
} catch (\PHPExiftool\Exception\TagUnknown $e) {
continue; continue;
} }
$multi = $meta->is_multi();
$type = $meta->get_type();
$datas = $field->get_values(); $datas = $field->get_values();
if ($multi) { if ($meta->is_multi()) {
foreach ($datas as $value) { $value = new Value\Multi($datas);
$value = $this->format_value($type, $value->getValue());
$subCMD .= ' -' . $meta->get_metadata_namespace() . ':' . $meta->get_metadata_tagname() . '=';
$subCMD .= escapeshellarg($value) . ' ';
}
} else { } else {
$value = array_pop($datas); $value = new Value\Mono(array_pop($datas));
$datas = $this->format_value($type, $value->getValue());
$subCMD .= ' -' . $meta->get_metadata_namespace() . ':' . $meta->get_metadata_tagname() . '=';
$subCMD .= escapeshellarg($datas) . ' ';
} }
$metadatas->add(
new Metadata\Metadata($tag, $value)
);
} }
$writer = new Writer();
foreach ($tsub as $name => $file) { foreach ($tsub as $name => $file) {
$cmd = '';
if ($this->system == 'WINDOWS')
{
$cmd = 'start /B /LOW ';
}
$cmd .= __DIR__ . '/../../../../vendor/phpexiftool/exiftool/exiftool'
. ' -m -overwrite_original ';
if ($name != 'document' || $this->clear_doc)
$cmd .= ' -all:all= ';
$cmd .= ' -codedcharacterset=utf8 ';
$cmd .= $subCMD . ' ' . escapeshellarg($file);
$this->log(sprintf(('writing meta for sbas_id=%1$d - record_id=%2$d (%3$s)'), $this->sbas_id, $record_id, $name)); $this->log(sprintf(('writing meta for sbas_id=%1$d - record_id=%2$d (%3$s)'), $this->sbas_id, $record_id, $name));
$s = trim(shell_exec($cmd)); $writer->erase($name != 'document' || $this->clear_doc);
$this->log("\t" . $s); try {
$writer->write($file, $metadatas);
} catch (\PHPExiftool\Exception\Exception $e) {
}
} }
$writer = $metadatas = null;
return $this; return $this;
} }

View File

@@ -1428,4 +1428,109 @@ class unicode
return $string; return $string;
} }
/**
* Guess the charset of a string and returns the UTF-8 version
*
* @param string $string
* @return string
*/
public function toUTF8($string)
{
/**
* (8x except 85, 8C) + (9x except 9C) + (BC, BD, BE)
*/
static $macchars = "\x81\x82\x83\x84\x86\x87\x88\x89\x8A\x8B\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9D\x9E\x9F\xBC\xBD\xBE";
if (mb_convert_encoding(mb_convert_encoding($string, 'UTF-32', 'UTF-8'), 'UTF-8', 'UTF-32') == $string) {
$mac = mb_convert_encoding($string, 'windows-1252', 'UTF-8');
for ($i = strlen($mac); $i;) {
if (strpos($macchars, $mac[ -- $i]) !== false) {
return(iconv('MACINTOSH', 'UTF-8', $mac));
}
}
return($string);
} else {
for ($i = strlen($string); $i;) {
if (strpos($macchars, $string[ -- $i]) !== false) {
return(iconv('MACINTOSH', 'UTF-8', $string));
}
}
return(iconv('windows-1252', 'UTF-8', $string));
}
}
/**
* Removes ctrl chars (tous < 32 sauf 9,10,13)
*
* @staticvar null $a_in
* @staticvar null $a_out
* @param type $s
* @return type
*/
public function substituteCtrlCharacters($string, $substitution = '_')
{
static $chars_in = null;
if (is_null($chars_in)) {
$chars_in = array();
for ($cc = 0; $cc < 32; $cc ++ ) {
if (in_array($cc, array(9, 10, 13))) {
continue;
}
$chars_in[] = chr($cc);
}
}
return str_replace($chars_in, $substitution, $string);
}
/**
* Parse a string and try to return the date normalized
*
* @example usage :
*
* //returns '2012/00/00 00:00:00'
* $unicode->parseDate('2012');
*
* @todo timezonify
*
* @param string $date
* @return string
*/
public function parseDate($date)
{
$date = str_replace(array('-', ':', '/', '.'), ' ', $date);
$date_yyyy = $date_mm = $date_dd = $date_hh = $date_ii = $date_ss = 0;
switch (sscanf($date, '%d %d %d %d %d %d', $date_yyyy, $date_mm, $date_dd, $date_hh, $date_ii, $date_ss)) {
case 1:
$date = sprintf('%04d/00/00 00:00:00', $date_yyyy);
break;
case 2:
$date = sprintf('%04d/%02d/00 00:00:00', $date_yyyy, $date_mm);
break;
case 3:
$date = sprintf('%04d/%02d/%02d 00:00:00', $date_yyyy, $date_mm, $date_dd);
break;
case 4:
$date = sprintf('%04d/%02d/%02d %02d:00:00', $date_yyyy, $date_mm, $date_dd, $date_hh);
break;
case 5:
$date = sprintf('%04d/%02d/%02d %02d:%02d:00', $date_yyyy, $date_mm, $date_dd, $date_hh, $date_ii);
break;
case 6:
$date = sprintf('%04d/%02d/%02d %02d:%02d:%02d', $date_yyyy, $date_mm, $date_dd, $date_hh, $date_ii, $date_ss);
break;
default:
$date = '0000/00/00 00:00:00';
}
return $date;
}
} }

View File

@@ -349,27 +349,29 @@
width="{{thumbnail.get_width()}}" width="{{thumbnail.get_width()}}"
height="{{thumbnail.get_height()}}" /> height="{{thumbnail.get_height()}}" />
{#{% if record is not none %}
<h1><b>{{record.get_title()}}</b></h1>
{% endif %}#}
<div> <div>
<h1><b>HTML</b></h1> <h1><b>Metadatas</b></h1>
<hr> <hr>
{% for line in metadatasFirst %} <table>
{% spaceless %} <tbody>
{{line|raw}} <tr>
{% endspaceless %} <td>
{% endfor %} </td>
</div> <td>
</td>
<div> </tr>
<h1><b>XML</b></h1> {% for metadata in metadatas %}
<hr /> <tr>
{% for line in metadatasSecond %} <td>
{{line|raw}}<br/> {{ metadata.getTag().getTagname() }}
{% endfor %} </td>
<td>
{{ metadata.getValue().getValue() }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div> </div>
</div> </div>
{% endfor %} {% endfor %}

View File

@@ -0,0 +1 @@
Un <20>l<EFBFBD>phant <20>a trompe <20>norm<72>ment !

View File

@@ -0,0 +1 @@
Un <20>l<EFBFBD>phant <20>a trompe <20>norm<72>ment !

View File

@@ -0,0 +1 @@
Un <20>l<EFBFBD>phant <20>a trompe <20>norm<72>ment !

View File

@@ -0,0 +1 @@
Un <20>l<EFBFBD>phant <20>a trompe <20>norm<72>ment !

View File

@@ -0,0 +1 @@
Un éléphant ça trompe énormément !

View File

@@ -0,0 +1 @@
Un <20>l<EFBFBD>phant <20>a trompe <20>norm<72>ment !

View File

@@ -0,0 +1 @@
Un <20>l<EFBFBD>phant <20>a trompe <20>norm<72>ment !

View File

@@ -4,18 +4,23 @@ require_once __DIR__ . '/PhraseanetPHPUnitAbstract.class.inc';
class unicodeTest extends PhraseanetPHPUnitAbstract class unicodeTest extends PhraseanetPHPUnitAbstract
{ {
/** /**
* @var unicode * @var unicode
*/ */
protected $object; protected $object;
/**
* @covers \unicode::__construct
*/
public function setUp() public function setUp()
{ {
parent::setUp(); parent::setUp();
$this->object = new unicode(); $this->object = new unicode();
} }
/**
* @covers \unicode::remove_diacritics
*/
public function testRemove_diacritics() public function testRemove_diacritics()
{ {
$this->assertEquals('Elephant', $this->object->remove_diacritics('Eléphant')); $this->assertEquals('Elephant', $this->object->remove_diacritics('Eléphant'));
@@ -23,6 +28,9 @@ class unicodeTest extends PhraseanetPHPUnitAbstract
$this->assertEquals('PeTARDS', $this->object->remove_diacritics('PéTARDS')); $this->assertEquals('PeTARDS', $this->object->remove_diacritics('PéTARDS'));
} }
/**
* @covers \unicode::remove_nonazAZ09
*/
public function testRemove_nonazAZ09() public function testRemove_nonazAZ09()
{ {
$this->assertEquals('Elephant', $this->object->remove_nonazAZ09('Eléphant')); $this->assertEquals('Elephant', $this->object->remove_nonazAZ09('Eléphant'));
@@ -33,6 +41,9 @@ class unicodeTest extends PhraseanetPHPUnitAbstract
$this->assertEquals('PeTARDS', $this->object->remove_nonazAZ09('PéTARDS')); $this->assertEquals('PeTARDS', $this->object->remove_nonazAZ09('PéTARDS'));
} }
/**
* @covers \unicode::remove_first_digits
*/
public function testRemove_first_digits() public function testRemove_first_digits()
{ {
$this->assertEquals('', $this->object->remove_first_digits('123456789')); $this->assertEquals('', $this->object->remove_first_digits('123456789'));
@@ -41,5 +52,44 @@ class unicodeTest extends PhraseanetPHPUnitAbstract
$this->assertEquals('a2b5cdeé', $this->object->remove_first_digits('4a2b5cdeé')); $this->assertEquals('a2b5cdeé', $this->object->remove_first_digits('4a2b5cdeé'));
} }
public function testSubstituteCtrlCharacters()
{
$string = 'Hello' . chr(30) . 'World !';
$this->assertEquals('Hello+World !', $this->object->substituteCtrlCharacters($string, '+'));
$string = 'Hello' . chr(9) . 'World !';
$this->assertEquals($string, $this->object->substituteCtrlCharacters($string, '+'));
}
/**
* @covers \unicode::toUTF8
*/
public function testToUTF8()
{
$reference = 'Un éléphant ça trompe énormément !';
$this->assertEquals($reference, $this->object->toUTF8(file_get_contents(__DIR__ . '/testfiles/MacOSRoman.txt')));
$this->assertEquals($reference, $this->object->toUTF8(file_get_contents(__DIR__ . '/testfiles/ISOLatin1.txt')));
$this->assertEquals($reference, $this->object->toUTF8(file_get_contents(__DIR__ . '/testfiles/ISOLatin2.txt')));
$this->assertEquals($reference, $this->object->toUTF8(file_get_contents(__DIR__ . '/testfiles/Latin5.txt')));
$this->assertEquals($reference, $this->object->toUTF8(file_get_contents(__DIR__ . '/testfiles/UTF-8.txt')));
$this->assertEquals($reference, $this->object->toUTF8(file_get_contents(__DIR__ . '/testfiles/WindowsLatin1.txt')));
$this->assertEquals($reference, $this->object->toUTF8(file_get_contents(__DIR__ . '/testfiles/WindowsLatin2.txt')));
}
/**
* @covers \unicode::parseDate
*/
public function testparseDate()
{
$date = '2012';
$this->assertEquals('2012/00/00 00:00:00', $this->object->parseDate('2012'));
$this->assertEquals('2012/01/00 00:00:00', $this->object->parseDate('2012-01'));
$this->assertEquals('2012/03/15 00:00:00', $this->object->parseDate('2012-03-15'));
$this->assertEquals('2012/03/15 12:00:00', $this->object->parseDate('2012-03-15 12'));
$this->assertEquals('2012/03/15 12:11:00', $this->object->parseDate('2012-03-15 12:11'));
$this->assertEquals('2012/03/15 12:12:12', $this->object->parseDate('2012-03-15 12-12-12'));
}
} }