Skip to content

Commit

Permalink
Merge pull request #9 from ElementareTeilchen/patch-3
Browse files Browse the repository at this point in the history
Style fixes, Singletons, Exceptions instead of Checks
  • Loading branch information
daniellienert authored Mar 22, 2017
2 parents 8da9807 + 4cc1b2e commit 7c46b7e
Show file tree
Hide file tree
Showing 20 changed files with 320 additions and 268 deletions.
5 changes: 4 additions & 1 deletion Classes/Converter/CoordinatesConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@
* source code.
*/

use Neos\Flow\Annotations as Flow;

/**
* @Flow\Scope("singleton")
* @see http://www.cipa.jp/std/documents/e/DC-008-Translation-2016-E.pdf data type definitions
*/
class CoordinatesConverter
{
/**
* Converts coordinates in DMS (degrees, minutes, seconds) and the cardinal direction reference (E,W,N,S) into
* Converts coordinates in DMS (degrees, minutes, seconds) and the cardinal direction reference (E,W,N,S) into
* DD (decimal degrees) notation.
*
* @param array<float> $dmsArray Coordinates in DMS (degrees, minutes, seconds)
Expand Down
5 changes: 5 additions & 0 deletions Classes/Converter/NumberConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
* source code.
*/

use Neos\Flow\Annotations as Flow;

/**
* @Flow\Scope("singleton")
*/
class NumberConverter
{
/**
Expand Down
54 changes: 27 additions & 27 deletions Classes/Domain/ExtractionManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,22 @@
* source code.
*/

use Neos\MetaData\Domain\Collection\MetaDataCollection;
use Neos\MetaData\Domain\Dto;
use Neos\MetaData\Extractor\Domain\Extractor\ExtractorInterface;
use Neos\MetaData\Extractor\Exception\ExtractorException;
use Neos\MetaData\MetaDataManager;
use Neos\Media\Domain\Model\ImageVariant;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\ObjectManagement\ObjectManager;
use Neos\Flow\Reflection\ReflectionService;
use Neos\Flow\ResourceManagement\PersistentResource as FlowResource;
use Neos\Media\Domain\Model\Asset;
use Neos\Media\Domain\Model\AssetCollection;
use Neos\Media\Domain\Model\ImageVariant;
use Neos\Media\Domain\Model\Tag;
use Neos\MetaData\Domain\Collection\MetaDataCollection;
use Neos\MetaData\Domain\Dto;
use Neos\MetaData\Extractor\Domain\Extractor\ExtractorInterface;
use Neos\MetaData\Extractor\Exception\ExtractorException;
use Neos\MetaData\MetaDataManager;

/**
* ExtractionManager
* @Flow\Scope("singleton")
*/
class ExtractionManager
{
Expand Down Expand Up @@ -62,7 +62,7 @@ public function extractMetaData(Asset $asset)

$flowResource = $asset->getResource();
if ($flowResource === null) {
throw new ExtractorException('Resource of Asset "' . $asset->getTitle() . '"" not found.', 201611111954);
throw new ExtractorException('Resource of Asset "' . $asset->getTitle() . '"" not found.', 1484060541);
}

$metaDataCollection = new MetaDataCollection();
Expand All @@ -75,6 +75,7 @@ public function extractMetaData(Asset $asset)
try {
$suitableAdapter->extractMetaData($flowResource, $metaDataCollection);
} catch (ExtractorException $exception) {
//Extractor is theoretically suitable but failed to extract meta data
continue;
}
}
Expand All @@ -84,24 +85,6 @@ public function extractMetaData(Asset $asset)
return $metaDataCollection;
}

/**
* @param FlowResource $flowResource
*
* @return array
*/
protected function findSuitableExtractorAdaptersForResource(FlowResource $flowResource)
{
$extractorAdapters = $this->reflectionService->getAllImplementationClassNamesForInterface(ExtractorInterface::class);
$mediaType = $flowResource->getMediaType();

$suitableAdapterClasses = array_filter($extractorAdapters, function ($extractorAdapterClass) use ($flowResource) {
/** @var ExtractorInterface $extractorAdapterClass */
return $extractorAdapterClass::isSuitableFor($flowResource);
});

return $suitableAdapterClasses;
}

/**
* @param Asset $asset
* @param MetaDataCollection $metaDataCollection
Expand All @@ -127,8 +110,25 @@ protected function buildAssetMetaData(Asset $asset, MetaDataCollection $metaData
'FileName' => $asset->getResource()->getFilename(),
'Collections' => $collections,
'Tags' => $tags,
'AssetObject' => $asset
'AssetObject' => $asset,
]);
$metaDataCollection->set('asset', $assetDto);
}

/**
* @param FlowResource $flowResource
*
* @return array
*/
protected function findSuitableExtractorAdaptersForResource(FlowResource $flowResource)
{
$extractorAdapters = $this->reflectionService->getAllImplementationClassNamesForInterface(ExtractorInterface::class);

$suitableAdapterClasses = array_filter($extractorAdapters, function ($extractorAdapterClass) use ($flowResource) {
/** @var ExtractorInterface $extractorAdapterClass */
return $extractorAdapterClass::isSuitableFor($flowResource);
});

return $suitableAdapterClasses;
}
}
7 changes: 4 additions & 3 deletions Classes/Domain/Extractor/AbstractExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
* source code.
*/

use Neos\Flow\ResourceManagement\PersistentResource;
use Neos\Utility\MediaTypes;
use Neos\Flow\ResourceManagement\PersistentResource as PersistentResource;

abstract class AbstractExtractor implements ExtractorInterface
{
Expand All @@ -28,10 +28,11 @@ abstract class AbstractExtractor implements ExtractorInterface
*/
public static function isSuitableFor(PersistentResource $resource)
{
$mediaType = $resource->getMediaType();
foreach (static::$compatibleMediaTypes as $compatibleMediaType) {
if(MediaTypes::mediaRangeMatches($compatibleMediaType, $resource->getMediaType()) === true) {
if (MediaTypes::mediaRangeMatches($compatibleMediaType, $mediaType)) {
return true;
};
}
}

return false;
Expand Down
141 changes: 74 additions & 67 deletions Classes/Domain/Extractor/ExifExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@
* source code.
*/

use Neos\MetaData\Extractor\Exception\ExtractorException;
use Neos\MetaData\Extractor\Specifications\Exif;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\ResourceManagement\Exception as FlowResourceException;
use Neos\Flow\ResourceManagement\PersistentResource as FlowResource;
use Neos\MetaData\Domain\Collection\MetaDataCollection;
use Neos\MetaData\Domain\Dto;
use Neos\MetaData\Extractor\Converter\CoordinatesConverter;
use Neos\MetaData\Extractor\Converter\NumberConverter;
use Neos\MetaData\Extractor\Converter\DateConverter;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\ResourceManagement\PersistentResource as FlowResource;
use Neos\MetaData\Extractor\Exception\ExtractorException;
use Neos\MetaData\Extractor\Specifications\Exif;

/**
* @see http://www.cipa.jp/std/documents/e/DC-008-Translation-2016-E.pdf Official standard
*
* @Flow\Scope("singleton")
* @see http://www.cipa.jp/std/documents/e/DC-008-Translation-2016-E.pdf Official standard
*/
class ExifExtractor extends AbstractExtractor
{
Expand All @@ -34,7 +34,7 @@ class ExifExtractor extends AbstractExtractor
protected static $compatibleMediaTypes = [
'image/jpeg',
'video/jpeg',
'image/tiff'
'image/tiff',
];

/**
Expand All @@ -59,7 +59,7 @@ class ExifExtractor extends AbstractExtractor
'UndefinedTag:0xA432' => 'LensSpecification',
'UndefinedTag:0xA433' => 'LensMake',
'UndefinedTag:0xA434' => 'LensModel',
'UndefinedTag:0xA435' => 'LensSerialNumber'
'UndefinedTag:0xA435' => 'LensSerialNumber',
];

/**
Expand Down Expand Up @@ -98,7 +98,7 @@ class ExifExtractor extends AbstractExtractor
'Temperature',
'WaterDepth',
'XResolution',
'YResolution'
'YResolution',
];

/**
Expand All @@ -114,7 +114,7 @@ class ExifExtractor extends AbstractExtractor
'GPSLongitude',
'GPSLatitude',
'GPSDestLongitude',
'GPSDestLatitude'
'GPSDestLatitude',
];

/**
Expand All @@ -124,100 +124,107 @@ class ExifExtractor extends AbstractExtractor
'GPSLongitude',
'GPSLatitude',
'GPSDestLongitude',
'GPSDestLatitude'
'GPSDestLatitude',
];

/**
* @var array
*/
protected static $subSecondProperties = [
'SubSecTime' => 'DateTime',
'SubSecTimeOriginal' => 'DateTimeOriginal',
'SubSecTimeDigitized' => 'DateTimeDigitized',
];

/**
* @var array
*/
protected static $timeOffsetProperties = [
'OffsetTime' => 'DateTime',
'OffsetTimeOriginal' => 'DateTimeOriginal',
'OffsetTimeDigitized' => 'DateTimeDigitized',
];

/**
* @param FlowResource $resource
* @param MetaDataCollection $metaDataCollection
*
* @throws ExtractorException
* @inheritdoc
*/
public function extractMetaData(FlowResource $resource, MetaDataCollection $metaDataCollection)
{
$convertedExifData = exif_read_data($resource->createTemporaryLocalCopy(), 'EXIF');
if ($convertedExifData === false) {
throw new ExtractorException(sprintf('EXIF data of flow resource %s could not be extracted.', $resource->getSha1()), 1486675463);
try {
$exifData = @exif_read_data($resource->createTemporaryLocalCopy(), 'EXIF');
} catch (FlowResourceException $exception) {
throw new ExtractorException('Could not extract EXIF data from ' . $resource->getFilename(), 1484059228, $e);
}
if ($exifData === false) {
throw new ExtractorException('Could not extract EXIF data from ' . $resource->getFilename(), 1484056779);
}

foreach (static::$deprecatedOrUnmappedProperties as $deprecatedOrUnmappedProperty => $newProperty) {
if (isset($convertedExifData[$deprecatedOrUnmappedProperty])) {
$convertedExifData[$newProperty] = $convertedExifData[$deprecatedOrUnmappedProperty];
unset($convertedExifData[$deprecatedOrUnmappedProperty]);
if (isset($exifData[$deprecatedOrUnmappedProperty])) {
$exifData[$newProperty] = $exifData[$deprecatedOrUnmappedProperty];
unset($exifData[$deprecatedOrUnmappedProperty]);
}
}

foreach (static::$rationalProperties as $rationalProperty) {
if (isset($convertedExifData[$rationalProperty])) {
$convertedExifData[$rationalProperty] = NumberConverter::convertRationalToFloat($convertedExifData[$rationalProperty]);
if (isset($exifData[$rationalProperty])) {
$exifData[$rationalProperty] = NumberConverter::convertRationalToFloat($exifData[$rationalProperty]);
}
}

foreach (static::$rationalArrayProperties as $rationalArrayProperty) {
if (isset($convertedExifData[$rationalArrayProperty])) {
foreach ($convertedExifData[$rationalArrayProperty] as $key => $value) {
$convertedExifData[$rationalArrayProperty][$key] = NumberConverter::convertRationalToFloat($value);
if (isset($exifData[$rationalArrayProperty])) {
foreach ($exifData[$rationalArrayProperty] as $key => $value) {
$exifData[$rationalArrayProperty][$key] = NumberConverter::convertRationalToFloat($value);
}
}
}

if (isset($convertedExifData['GPSVersionID'])) {
$convertedExifData['GPSVersionID'] = NumberConverter::convertBinaryToVersion($convertedExifData['GPSVersionID']);
if (isset($exifData['GPSVersionID'])) {
$exifData['GPSVersionID'] = NumberConverter::convertBinaryToVersion($exifData['GPSVersionID']);
}

if (isset($convertedExifData['GPSAltitudeRef'], $convertedExifData['GPSAltitude'])) {
if ($convertedExifData['GPSAltitudeRef'] === 1) {
$convertedExifData['GPSAltitude'] = -$convertedExifData['GPSAltitude'];
if (isset($exifData['GPSAltitudeRef'], $exifData['GPSAltitude'])) {
if ($exifData['GPSAltitudeRef'] === 1) {
$exifData['GPSAltitude'] = -$exifData['GPSAltitude'];
}
unset($convertedExifData['GPSAltitudeRef']);
unset($exifData['GPSAltitudeRef']);
}

foreach (static::$gpsProperties as $gpsProperty) {
if (isset($convertedExifData[$gpsProperty])) {
$convertedExifData[$gpsProperty] = CoordinatesConverter::convertDmsToDd($convertedExifData[$gpsProperty], isset($convertedExifData[$gpsProperty . 'Ref']) ? $convertedExifData[$gpsProperty . 'Ref'] : null);
unset($convertedExifData[$gpsProperty . 'Ref']);
if (isset($exifData[$gpsProperty])) {
$exifData[$gpsProperty] = CoordinatesConverter::convertDmsToDd($exifData[$gpsProperty], isset($exifData[$gpsProperty . 'Ref']) ? $exifData[$gpsProperty . 'Ref'] : null);
unset($exifData[$gpsProperty . 'Ref']);
}
}

if (isset($convertedExifData['GPSTimeStamp'], $convertedExifData['GPSDateStamp'])) {
$convertedExifData['GPSDateTimeStamp'] = DateConverter::convertGpsDateAndTime($convertedExifData['GPSDateStamp'], $convertedExifData['GPSTimeStamp']);
unset($convertedExifData['GPSTimeStamp'], $convertedExifData['GPSDateStamp']);
if (isset($exifData['GPSTimeStamp'], $exifData['GPSDateStamp'])) {
$exifData['GPSDateTimeStamp'] = DateConverter::convertGpsDateAndTime($exifData['GPSDateStamp'], $exifData['GPSTimeStamp']);
unset($exifData['GPSTimeStamp'], $exifData['GPSDateStamp']);
}

foreach ($convertedExifData as $property => $value) {
$convertedExifData[$property] = Exif::interpretValue($property, $value);
foreach ($exifData as $property => $value) {
$exifData[$property] = Exif::interpretValue($property, $value);
}

$subSecondProperties = [
'SubSecTime' => 'DateTime',
'SubSecTimeOriginal' => 'DateTimeOriginal',
'SubSecTimeDigitized' => 'DateTimeDigitized'
];

foreach ($subSecondProperties as $subSecondProperty => $dateTimeProperty) {
if (isset($convertedExifData[$subSecondProperty], $convertedExifData[$dateTimeProperty])) {
$convertedExifData[$dateTimeProperty] = \DateTime::createFromFormat('Y-m-d H:i:s.u', $convertedExifData[$dateTimeProperty]->format('Y-m-d H:i:s.') . $convertedExifData[$subSecondProperty]);
unset($convertedExifData[$subSecondProperty]);
foreach (static::$subSecondProperties as $subSecondProperty => $dateTimeProperty) {
if (isset($exifData[$subSecondProperty], $exifData[$dateTimeProperty])) {
$exifData[$dateTimeProperty] = \DateTime::createFromFormat('Y-m-d H:i:s.u', $exifData[$dateTimeProperty]->format('Y-m-d H:i:s.') . $exifData[$subSecondProperty]);
unset($exifData[$subSecondProperty]);
}
}

$timeOffsetProperties = [
'OffsetTime' => 'DateTime',
'OffsetTimeOriginal' => 'DateTimeOriginal',
'OffsetTimeDigitized' => 'DateTimeDigitized',
];

foreach ($timeOffsetProperties as $timeOffsetProperty => $dateTimeProperty) {
if (isset($convertedExifData[$timeOffsetProperty], $convertedExifData[$dateTimeProperty])) {
$convertedExifData[$dateTimeProperty] = \DateTime::createFromFormat('Y-m-d H:i:s.uP', $convertedExifData[$dateTimeProperty]->format('Y-m-d H:i:s.u') . $convertedExifData[$timeOffsetProperty]);
unset($convertedExifData[$timeOffsetProperty]);
foreach (static::$timeOffsetProperties as $timeOffsetProperty => $dateTimeProperty) {
if (isset($exifData[$timeOffsetProperty], $exifData[$dateTimeProperty])) {
$exifData[$dateTimeProperty] = \DateTime::createFromFormat('Y-m-d H:i:s.uP', $exifData[$dateTimeProperty]->format('Y-m-d H:i:s.u') . $exifData[$timeOffsetProperty]);
unset($exifData[$timeOffsetProperty]);
}
}

// wrongly encoded UserComment breaks saving of the whole data set, so check for correct encoding and remove if necessary
if (isset($convertedExifData['UserComment'])) {
$characterCode = substr($convertedExifData['UserComment'], 0, 8);
$value = substr($convertedExifData['UserComment'], 8);
if (isset($exifData['UserComment'])) {
$characterCode = substr($exifData['UserComment'], 0, 8);
$value = substr($exifData['UserComment'], 8);
switch ($characterCode) {
case chr(0x41) . chr(0x53) . chr(0x43) . chr(0x49) . chr(0x49) . chr(0x0) . chr(0x0) . chr(0x0): // ASCII
$encoding = 'US-ASCII';
Expand All @@ -232,15 +239,15 @@ public function extractMetaData(FlowResource $resource, MetaDataCollection $meta
case chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0): // Undefined
// try it with ASCII anyway
$encoding = 'ASCII';
$value = $convertedExifData['UserComment'];
$value = $exifData['UserComment'];
}
if (mb_check_encoding($value, $encoding)) {
$convertedExifData['UserComment'] = $value;
$exifData['UserComment'] = $value;
} else {
unset($convertedExifData['UserComment']);
unset($exifData['UserComment']);
}
}

$metaDataCollection->set('exif', new Dto\Exif($convertedExifData));
$metaDataCollection->set('exif', new Dto\Exif($exifData));
}
}
Loading

0 comments on commit 7c46b7e

Please sign in to comment.