Skip to content

Commit

Permalink
Merge branch '1'
Browse files Browse the repository at this point in the history
This merge contains the new auto-tagging feature.
#7
  • Loading branch information
robertlemke committed Apr 24, 2020
2 parents d766b21 + 2e347e8 commit 094f36e
Show file tree
Hide file tree
Showing 8 changed files with 433 additions and 150 deletions.
21 changes: 19 additions & 2 deletions Classes/AssetSource/PixxioAssetProxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

use Behat\Transliterator\Transliterator;
use GuzzleHttp\Psr7\Uri;
use Exception;
use Neos\Media\Domain\Model\AssetSource\AssetProxy\AssetProxyInterface;
use Neos\Media\Domain\Model\AssetSource\AssetProxy\HasRemoteOriginalInterface;
use Neos\Media\Domain\Model\AssetSource\AssetProxy\SupportsIptcMetadataInterface;
Expand All @@ -24,6 +25,7 @@
use Neos\Utility\MediaTypes;
use Psr\Http\Message\UriInterface;
use Neos\Flow\Annotations as Flow;
use stdClass;

/**
*
Expand Down Expand Up @@ -95,18 +97,24 @@ final class PixxioAssetProxy implements AssetProxyInterface, HasRemoteOriginalIn
*/
private $heightInPixels;

/**
* @var array
*/
private $tags = [];

/**
* @Flow\Inject
* @var ImportedAssetRepository
*/
protected $importedAssetRepository;

/**
* @param \stdClass $jsonObject
* @param stdClass $jsonObject
* @param PixxioAssetSource $assetSource
* @return static
* @throws Exception
*/
static public function fromJsonObject(\stdClass $jsonObject, PixxioAssetSource $assetSource)
public static function fromJsonObject(stdClass $jsonObject, PixxioAssetSource $assetSource): PixxioAssetProxy
{
$assetSourceOptions = $assetSource->getAssetSourceOptions();
$pixxioOriginalMediaType = MediaTypes::getMediaTypeFromFilename('foo.' . strtolower($jsonObject->fileType));;
Expand All @@ -121,6 +129,7 @@ static public function fromJsonObject(\stdClass $jsonObject, PixxioAssetSource $
$assetProxy->lastModified = new \DateTime($jsonObject->modifyDate ?? '1.1.2000');
$assetProxy->fileSize = $jsonObject->fileSize;
$assetProxy->mediaType = MediaTypes::getMediaTypeFromFilename('foo.' . $modifiedFileType);
$assetProxy->tags = isset($jsonObject->keywords) ? explode(',', $jsonObject->keywords) : [];

$assetProxy->iptcProperties['Title'] = $jsonObject->subject ?? '';
$assetProxy->iptcProperties['CaptionAbstract'] = $jsonObject->description ?? '';
Expand Down Expand Up @@ -290,6 +299,14 @@ public function getLocalAssetIdentifier(): ?string
return ($importedAsset instanceof ImportedAsset ? $importedAsset->getLocalAssetIdentifier() : null);
}

/**
* @return array
*/
public function getTags(): array
{
return $this->tags;
}

/**
* @return bool
*/
Expand Down
18 changes: 16 additions & 2 deletions Classes/AssetSource/PixxioAssetProxyRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@
* source code.
*/

use Exception;
use Flownative\Pixxio\Exception\AssetNotFoundException;
use Flownative\Pixxio\Exception\AuthenticationFailedException;
use Flownative\Pixxio\Exception\ConnectionException;
use Flownative\Pixxio\Exception\MissingClientSecretException;
use Neos\Cache\Frontend\StringFrontend;
use Neos\Cache\Frontend\VariableFrontend;
use Neos\Flow\ObjectManagement\DependencyInjection\DependencyProxy;
use Neos\Media\Domain\Model\AssetSource\AssetNotFoundExceptionInterface;
use Neos\Media\Domain\Model\AssetSource\AssetProxy\AssetProxyInterface;
use Neos\Media\Domain\Model\AssetSource\AssetProxyQueryResultInterface;
Expand Down Expand Up @@ -56,7 +59,7 @@ public function __construct(PixxioAssetSource $assetSource)
private $orderings = [];

/**
* @var VariableFrontend
* @var StringFrontend
*/
protected $assetProxyCache;

Expand All @@ -70,6 +73,7 @@ public function __construct(PixxioAssetSource $assetSource)
* @throws AssetNotFoundException
* @throws ConnectionException
* @throws \Neos\Cache\Exception
* @throws Exception
*/
public function getAssetProxy(string $identifier): AssetProxyInterface
{
Expand Down Expand Up @@ -157,7 +161,6 @@ public function countAll(): int
return $query->count();
}


/**
* Sets the property names to order results by. Expected like this:
* array(
Expand All @@ -173,4 +176,15 @@ public function orderBy(array $orderings): void
{
$this->orderings = $orderings;
}

/**
* @return StringFrontend
*/
public function getAssetProxyCache(): StringFrontend
{
if ($this->assetProxyCache instanceof DependencyProxy) {
$this->assetProxyCache->_activateDependency();
}
return $this->assetProxyCache;
}
}
60 changes: 54 additions & 6 deletions Classes/AssetSource/PixxioAssetSource.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,12 @@
use Flownative\Pixxio\Service\PixxioServiceFactory;
use GuzzleHttp\Psr7\Uri;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Security\Account;
use Neos\Flow\Security\Context;
use Neos\Media\Domain\Model\AssetSource\AssetProxyRepositoryInterface;
use Neos\Media\Domain\Model\AssetSource\AssetSourceInterface;
use Neos\Utility\MediaTypes;

/**
*
*/
class PixxioAssetSource implements AssetSourceInterface
{
/**
Expand Down Expand Up @@ -79,6 +77,16 @@ class PixxioAssetSource implements AssetSourceInterface
*/
private $pixxioClient;

/**
* @var bool
*/
private $autoTaggingEnable = false;

/**
* @var string
*/
private $autoTaggingInUseTag = 'used-by-neos';

/**
* @var array
*/
Expand Down Expand Up @@ -125,6 +133,23 @@ public function __construct(string $assetSourceIdentifier, array $assetSourceOpt
}
}
break;
case 'autoTagging':
if (!is_array($optionValue)) {
throw new \InvalidArgumentException(sprintf('Invalid auto tagging configuration specified for Pixx.io asset source %s', $assetSourceIdentifier), 1587561121);
}
foreach ($optionValue as $autoTaggingOptionName => $autoTaggingOptionValue) {
switch ($autoTaggingOptionName) {
case 'enable':
$this->autoTaggingEnable = (bool)$autoTaggingOptionValue;
break;
case 'inUseTag':
$this->autoTaggingInUseTag = preg_replace('/[^A-Za-z0-9&_+ßäöüÄÖÜ.@ -]+/u', '', (string)$autoTaggingOptionValue);
break;
default:
throw new \InvalidArgumentException(sprintf('Unknown asset source option "%s" specified for autoTagging in Pixx.io asset source "%s". Please check your settings.', $autoTaggingOptionName, $assetSourceIdentifier), 1587561244);
}
}
break;
default:
throw new \InvalidArgumentException(sprintf('Unknown asset source option "%s" specified for Pixx.io asset source "%s". Please check your settings.', $optionName, $assetSourceIdentifier), 1525790910);
}
Expand Down Expand Up @@ -185,6 +210,22 @@ public function getAssetSourceOptions(): array
return $this->assetSourceOptions;
}

/**
* @return bool
*/
public function isAutoTaggingEnabled(): bool
{
return $this->autoTaggingEnable;
}

/**
* @return string
*/
public function getAutoTaggingInUseTag(): string
{
return $this->autoTaggingInUseTag;
}

/**
* @return PixxioClient
* @throws MissingClientSecretException
Expand All @@ -193,10 +234,17 @@ public function getAssetSourceOptions(): array
public function getPixxioClient(): PixxioClient
{
if ($this->pixxioClient === null) {
$account = $this->securityContext->getAccount();
$clientSecret = $this->clientSecretRepository->findOneByFlowAccountIdentifier($account->getAccountIdentifier());

if (($clientSecret === null || $clientSecret->getRefreshToken() === '') && !empty($this->sharedRefreshToken)) {
if ($this->securityContext->isInitialized()) {
$account = $this->securityContext->getAccount();
$clientSecret = $this->clientSecretRepository->findOneByFlowAccountIdentifier($account->getAccountIdentifier());
} else {
$clientSecret = null;
$account = new Account();
$account->setAccountIdentifier('shared');
}

if (!empty($this->sharedRefreshToken) && ($clientSecret === null || $clientSecret->getRefreshToken() === '')) {
$clientSecret = new ClientSecret();
$clientSecret->setRefreshToken($this->sharedRefreshToken);
$clientSecret->setFlowAccountIdentifier('shared');
Expand Down
109 changes: 109 additions & 0 deletions Classes/Command/PixxioCommandController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php
namespace Flownative\Pixxio\Command;

use Flownative\Pixxio\AssetSource\PixxioAssetProxy;
use Flownative\Pixxio\AssetSource\PixxioAssetProxyRepository;
use Flownative\Pixxio\AssetSource\PixxioAssetSource;
use Flownative\Pixxio\Exception\AuthenticationFailedException;
use Flownative\Pixxio\Exception\Exception;
use Flownative\Pixxio\Exception\MissingClientSecretException;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Cli\CommandController;
use Neos\Media\Domain\Model\Asset;
use Neos\Media\Domain\Model\AssetSource\AssetSourceAwareInterface;
use Neos\Media\Domain\Repository\AssetRepository;

class PixxioCommandController extends CommandController
{
/**
* @Flow\Inject
* @var AssetRepository
*/
protected $assetRepository;

/**
* @Flow\InjectConfiguration(path="assetSources", package="Neos.Media")
* @var array
*/
protected $assetSourcesConfiguration;

/**
* Tag used assets
*
* @param string $assetSource Name of the pixxio asset source
* @param bool $quiet If set, only errors will be displayed.
* @return void
* @throws Exception
*/
public function tagUsedAssetsCommand(string $assetSource = 'flownative-pixxio', bool $quiet = false): void
{
$assetSourceIdentifier = $assetSource;
$iterator = $this->assetRepository->findAllIterator();

!$quiet && $this->outputLine('<b>Tagging used assets of asset source "%s" via Pixxio API:</b>', [$assetSourceIdentifier]);

try {
$pixxioAssetSource = new PixxioAssetSource($assetSourceIdentifier, $this->assetSourcesConfiguration[$assetSourceIdentifier]['assetSourceOptions']);
$pixxioClient = $pixxioAssetSource->getPixxioClient();
} catch (MissingClientSecretException $e) {
$this->outputLine('<error>Authentication error: Missing client secret</error>');
exit(1);
} catch (AuthenticationFailedException $e) {
$this->outputLine('<error>Authentication error: %s</error>', [$e->getMessage()]);
exit(1);
}

if (!$pixxioAssetSource->isAutoTaggingEnabled()) {
$this->outputLine('<error>Auto-tagging is disabled</error>');
exit(1);
}

$assetProxyRepository = $pixxioAssetSource->getAssetProxyRepository();
assert($assetProxyRepository instanceof PixxioAssetProxyRepository);
$assetProxyRepository->getAssetProxyCache()->flush();

foreach ($this->assetRepository->iterate($iterator) as $asset) {
if (!$asset instanceof Asset) {
continue;
}
if (!$asset instanceof AssetSourceAwareInterface) {
continue;
}
if ($asset->getAssetSourceIdentifier() !== $assetSourceIdentifier) {
continue;
}

$assetProxy = $asset->getAssetProxy();
if (!$assetProxy instanceof PixxioAssetProxy) {
$this->outputLine(' error No asset proxy found for %s', [$asset->getLabel()]);
continue;
}

$currentTags = $assetProxy->getTags();
sort($currentTags);
if ($asset->getUsageCount() > 0) {
$newTags = array_unique(array_merge($currentTags, [$pixxioAssetSource->getAutoTaggingInUseTag()]));
sort($newTags);

if ($currentTags !== $newTags) {
$pixxioClient->updateFile($assetProxy->getIdentifier(), ['keywords' => implode(',', $newTags)]);
$this->outputLine(' tagged %s %s (%s)', [$asset->getLabel(), $assetProxy->getIdentifier(), $asset->getUsageCount()]);
} else {
$this->outputLine(' (tagged) %s %s (%s)', [$asset->getLabel(), $assetProxy->getIdentifier(), $asset->getUsageCount()]);
}
} else {
$newTags = array_flip($currentTags);
unset($newTags[$pixxioAssetSource->getAutoTaggingInUseTag()]);
$newTags = array_flip($newTags);
sort($newTags);

if ($currentTags !== $newTags) {
$pixxioClient->updateFile($assetProxy->getIdentifier(), ['keywords' => implode(',', $newTags)]);
$this->outputLine(' removed %s', [$asset->getLabel(), $asset->getUsageCount()]);
} else {
$this->outputLine(' (removed) %s', [$asset->getLabel(), $asset->getUsageCount()]);
}
}
}
}
}
Loading

0 comments on commit 094f36e

Please sign in to comment.