Merge branch 'master' of https://github.com/alchemy-fr/Phraseanet into PHRAS-3555-more-webhook

This commit is contained in:
aynsix
2021-11-29 13:48:46 +03:00
4 changed files with 138 additions and 68 deletions

View File

@@ -61,8 +61,8 @@ trait JsonBodyAware
* @param null|string $schemaUri
* @return stdClass
*/
public function decodeJsonBody(Request $request, $schemaUri = null)
public function decodeJsonBody(Request $request, $schemaUri = null, $format = JsonBodyHelper::OBJECT)
{
return $this->getJsonBodyHelper()->decodeJsonBody($request, $schemaUri);
return $this->getJsonBodyHelper()->decodeJsonBody($request, $schemaUri, $format);
}
}

View File

@@ -9,11 +9,14 @@ use Alchemy\Phrasea\Border\Manager;
use Alchemy\Phrasea\Controller\Api\Result;
use Alchemy\Phrasea\Controller\Controller;
use Alchemy\Phrasea\Filesystem\FilesystemService;
use Alchemy\Phrasea\Helper\JsonBodyHelper;
use Alchemy\Phrasea\Media\SubdefGenerator;
use databox_subdef;
use Exception;
use Guzzle\Http\Client;
use Neutron\TemporaryFilesystem\TemporaryFilesystemInterface;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Translation\TranslatorInterface;
@@ -25,27 +28,43 @@ class V3SubdefsServiceController extends Controller
use DispatcherAware;
/**
* the internal route "api/v3/subdefs_service_callback" can be used to explore the data sent to service callback
* it will save the received file in logs, and log infos into logs/subdefgenerator.txt
*
* @param Request $request
* @return JsonResponse|Response
*/
public function callbackAction_POST(Request $request)
{
$logto = realpath(dirname(__FILE__).'/../../../../../../logs') . '/';
/** @var UploadedFile $file */
$file = $request->files->get('file');
/** @var string $body json supplemental infos */
$body = $request->get('body');
$info = $request->get('file_info');
file_put_contents(dirname(__FILE__).'/../../../../../../logs/subdefgenerator.txt', sprintf("\n%s [%s] : %s (%s); %s\n", (date('Y-m-d\TH:i:s')), getmypid(), __FILE__, __LINE__,
// save the received file
$src = $file->getRealPath();
$dst = $logto . $info['filename'];
copy($src, $dst);
// log
file_put_contents($logto. 'subdefgenerator.txt', sprintf("\n%s [%s] : %s (%s); %s\n", (date('Y-m-d\TH:i:s')), getmypid(), __FILE__, __LINE__,
sprintf(
"into callbackAction_POST with\n - file: \"%s\"\n - filesize: %d\n - body: \"%s\"" ,
"into callbackAction_POST with\n - file: \"%s\"\n - filesize: %d\n - saved to: \"%s\"\n - payload: %s" ,
$file->getRealPath(),
$file->getSize(),
$body
$dst,
var_export($request->request->all(), true)
)
), FILE_APPEND | LOCK_EX);
// for now the subdef service does not expect any result from the callback
// so this "ret" is for debug only
$ret = [
'message' => "subdef service callback was called",
'file' => $file->getRealPath(),
'filesize' => $file->getSize(),
'body' => $body
'filesize' => $file->getSize()
];
return Result::create($request, $ret)->createResponse();
@@ -62,7 +81,7 @@ class V3SubdefsServiceController extends Controller
*/
public function indexAction_POST(Request $request)
{
$body = $this->decodeJsonBody($request);
$body = $this->decodeJsonBody($request, null, JsonBodyHelper::OBJECT);
$dbox_id = $body->databoxId;
$databox = $this->app->getApplicationBox()->get_databox($dbox_id);
@@ -139,71 +158,96 @@ class V3SubdefsServiceController extends Controller
$media = $this->app->getMediaFromUri($sourceFile);
$type = $media->getType(); // 'document', 'audio', 'video', 'image', 'flash', 'map'
$subdefs = $databox->get_subdef_structure()->getSubdefGroup($type);
// $subdef = new \databox_subdef($type, $sxSettings, $this->getTranslator());
$phrSubdefs = []; // array of phr subdefs by name, will give the list of wanted subdefs (aliased by client)
$allWanted = []; // in case no wanted subdef was passed in body, prepare a full list
$type = $media->getType(); // 'document', 'audio', 'video', 'image', 'flash', 'map'
foreach($databox->get_subdef_structure()->getSubdefGroup($type) as $sd) {
$phrSubdefs[$sd->get_name()] = ['subdef' => $sd, 'destinations' => []];
$allWanted[$sd->get_name()] = ['source' => $sd->get_name()];
}
// list wanted subdefs
$wanted = (array)$body->destination->subdefs;
if(empty($wanted)) {
$wanted = $allWanted; // no list of wanted subdefs : send all
}
unset($allWanted);
// map a list of phr sources to a list of alias (wanted) names
foreach ($wanted as $w => $a) {
$a = (array) $a;
if(!array_key_exists($a['source'], $phrSubdefs)) {
// the source (phr subdef name) is unknown : ignore
continue;
}
$k = $a['source'];
unset($a['source']);
$phrSubdefs[$k]['destinations'][$w] = (array) $a;
}
$guzzle = new Client();
$guzzle->setSslVerification(false);
$postFilenameRoot = $body->destination->filename ?: "subdef";
$postFilenameRoot = $body->destination->filename ?: "subdef_";
$destPayload = $body->destination->payload ?: [];
try {
foreach ($subdefs as $subdef) {
if (is_array($body->destination->subdefs) && !in_array($subdef->get_name(), $body->destination->subdefs)) {
continue;
foreach ($phrSubdefs as $sd) {
/** @var databox_subdef $subdef */
$subdef = $sd['subdef'];
foreach ($sd['destinations'] as $destName => $destAttr) {
$postFilename = $postFilenameRoot . $destName;
$start = microtime(true);
$ext = $this->getFilesystemService()->getExtensionFromSpec($subdef->getSpecs());
/** @var string $destFile */
$destFile = $this->getTmpFilesystem()->createTemporaryFile(null, '_' . $subdef->get_name(), $ext);
$this->getSubdefGenerator()->generateSubdefFromFile($sourceFile, $subdef, $destFile);
$duration = microtime(true) - $start;
$postFilename .= '.' . $ext;
$data = [
'filename' => $postFilename,
'extension' => $ext,
'name' => $subdef->get_name(),
'class' => $subdef->get_class(),
'filesize' => filesize($destFile),
'build_duration' => $duration,
];
$start = microtime(true);
$postFields = array_merge((array)$destPayload, [
'file_info' => $data,
]);
try {
$guzzle->post($destination_url)
->addPostFields($postFields)
->addPostFile('file', $destFile, null, $postFilename)
->send();
}
catch (Exception $e) {
throw new Exception(sprintf(
'Failed to post subdef "%s" file: %s',
$subdef->get_name(),
$e->getMessage()
), 0, $e);
}
finally {
unlink($destFile);
}
$data['post_duration'] = microtime(true) - $start;
$ret['sent'][$subdef->get_name()] = $data;
}
$postFilename = $postFilenameRoot.'_'.$subdef->get_name();
$start = microtime(true);
$ext = $this->getFilesystemService()->getExtensionFromSpec($subdef->getSpecs());
/** @var string $destFile */
$destFile = $this->getTmpFilesystem()->createTemporaryFile(null, '_'.$subdef->get_name(), $ext);
$this->getSubdefGenerator()->generateSubdefFromFile($sourceFile, $subdef, $destFile);
$duration = microtime(true) - $start;
$postFilename .= '.'.$ext;
$data = [
'filename' => $postFilename,
'extension' => $ext,
'name' => $subdef->get_name(),
'class' => $subdef->get_class(),
'filesize' => filesize($destFile),
'build_duration' => $duration,
];
$start = microtime(true);
$postFields = array_merge((array)$destPayload, [
'file_info' => $data,
]);
try {
$guzzle->post($destination_url)
->addPostFields($postFields)
->addPostFile('file', $destFile, null, $postFilename)
->send();
} catch (Exception $e) {
throw new Exception(sprintf(
'Failed to post subdef "%s" file: %s',
$subdef->get_name(),
$e->getMessage()
), 0, $e);
} finally {
unlink($destFile);
}
$data['post_duration'] = microtime(true) - $start;
$ret['sent'][$subdef->get_name()] = $data;
}
} finally {
unlink($sourceFile);

View File

@@ -21,6 +21,16 @@ use Webmozart\Json\ValidationFailedException;
class JsonBodyHelper
{
/**
* Decode a JSON value as PHP object.
*/
const OBJECT = 0;
/**
* Decode a JSON value as associative array.
*/
const ASSOC_ARRAY = 1;
/** @var JsonValidator */
private $validator;
/** @var JsonDecoder */
@@ -60,7 +70,7 @@ class JsonBodyHelper
* @param null|string|object $schemaUri
* @return mixed
*/
public function decodeJsonBody(Request $request, $schemaUri = null)
public function decodeJsonBody(Request $request, $schemaUri = null, $format = self::OBJECT)
{
if(empty($content = $request->getContent())) {
// in case of multipart/form-data (e.g. to upload a file), the only way to send
@@ -72,6 +82,7 @@ class JsonBodyHelper
$schema = $schemaUri ? $this->retrieveSchema($schemaUri) : null;
try {
$this->decoder->setObjectDecoding($format===self::ASSOC_ARRAY ? $this->decoder::ASSOC_ARRAY : $this->decoder::OBJECT);
return $this->decoder->decode($content, $schema);
} catch (DecodingFailedException $exception) {
throw new UnprocessableEntityHttpException('Json request cannot be decoded', $exception);

View File

@@ -286,7 +286,7 @@ class SubdefGenerator
$this->logger->error(sprintf('Subdef generation failed for record %d with message %s', $record->getRecordId(), $e->getMessage()));
}
if($start){
if($start) {
// the subdef was done
@@ -422,6 +422,21 @@ class SubdefGenerator
$this->logger->error(sprintf('Subdef generation failed with message %s', $e->getMessage()));
}
// watermark ?
if($subdef_class->getSpecs() instanceof Image) {
/** @var Subdef\Image $image */
$image = $subdef_class->getSubdefType();
/** @var Boolean $wm */
$wm = $image->getOption(Subdef\Image::OPTION_WATERMARK);
if($wm->getValue()) {
// we must watermark the file
/** @var Text $wmt */
$wmt = $image->getOption(Subdef\Image::OPTION_WATERMARKTEXT);
$this->wartermarkImageFile($pathdest, $wmt->getValue());
}
}
$duration = microtime(true) - $start;
$originFileSize = $this->sizeHumanReadable(filesize($pathSrc));