Skip to content

Commit

Permalink
PHRAS-3870_record-action-example (#4334)
Browse files Browse the repository at this point in the history
* select by id or name ; add / enhance clauses (date, number, ...) ; change example to match default db ; add doc

* fix "in code" example

* big refacto ; bc break on syntax ; add "compute" ; allow b/c work:run-serv without payload

* exception if not settings/version=2

---------

Co-authored-by: Nicolas Maillat <[email protected]>
  • Loading branch information
jygaulier and nmaillat authored Aug 2, 2023
1 parent bfb58d8 commit 74757ca
Show file tree
Hide file tree
Showing 10 changed files with 1,536 additions and 662 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Alchemy\Phrasea\Command\Command;
use Alchemy\Phrasea\WorkerManager\Worker\Resolver\WorkerResolverInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
Expand All @@ -15,8 +16,8 @@ public function __construct()
parent::__construct('worker:run-service');

$this->setDescription('Execute a service')
->addArgument('type')
->addArgument('body')
->addArgument('type', InputArgument::REQUIRED)
->addArgument('body', InputArgument::OPTIONAL)
->addOption('preserve-payload', 'p', InputOption::VALUE_NONE, 'Preserve temporary payload file');

return $this;
Expand All @@ -28,28 +29,33 @@ protected function doExecute(InputInterface $input, OutputInterface $output)
$workerResolver = $this->container['alchemy_worker.type_based_worker_resolver'];

$type = $input->getArgument('type');
$body = file_get_contents($input->getArgument('body'));
$body = $input->getArgument('body');

if ($body === false) {
$output->writeln('Unable to read payload file');

return;
}
$body = [];
if($input->getArgument('body')) {
$body = @file_get_contents($input->getArgument('body'));

if ($body === false) {
$output->writeln(sprintf('<error>Unable to read payload file %s</error>', $input->getArgument('body')));

$body = json_decode($body, true);
return;
}

if (json_last_error() !== JSON_ERROR_NONE) {
$output->writeln('<error>Invalid message body</error>');
$body = json_decode($body, true);
if (json_last_error() !== JSON_ERROR_NONE) {
$output->writeln('<error>Invalid message body</error>');

return;
return;
}
}

$worker = $workerResolver->getWorker($type, $body);

$worker->process($body);

if (! $input->getOption('preserve-payload')) {
unlink($input->getArgument('body'));
@unlink($input->getArgument('body'));
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Alchemy\Phrasea\Controller\Controller;
use Alchemy\Phrasea\Model\Entities\WorkerRunningJob;
use Alchemy\Phrasea\Model\Repositories\WorkerRunningJobRepository;
use Alchemy\Phrasea\Plugin\Exception\JsonValidationException;
use Alchemy\Phrasea\SearchEngine\Elastic\ElasticsearchOptions;
use Alchemy\Phrasea\Twig\PhraseanetExtension;
use Alchemy\Phrasea\WorkerManager\Event\PopulateIndexEvent;
Expand All @@ -17,8 +18,9 @@
use Alchemy\Phrasea\WorkerManager\Form\WorkerValidationReminderType;
use Alchemy\Phrasea\WorkerManager\Queue\AMQPConnection;
use Alchemy\Phrasea\WorkerManager\Queue\MessagePublisher;
use Alchemy\Phrasea\WorkerManager\Worker\RecordsActionsWorker;
use Alchemy\Phrasea\WorkerManager\Worker\RecordsActionsWorker\RecordsActionsWorker;
use Doctrine\ORM\OptimisticLockException;
use Exception;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormInterface;
Expand Down Expand Up @@ -117,7 +119,7 @@ public function infoAction(PhraseaApplication $app, Request $request)
if ($timeFilter != null) {
try {
$dateTimeFilter = (new \DateTime())->sub(new \DateInterval($timeFilter));
} catch (\Exception $e) {
} catch (Exception $e) {
}
}

Expand Down Expand Up @@ -509,28 +511,32 @@ public function recordsActionsAction(PhraseaApplication $app, Request $request)

public function recordsActionsFacilityAction(PhraseaApplication $app, Request $request)
{
$ret = ['tasks' => []];
$job = new RecordsActionsWorker($app);
switch ($request->get('ACT')) {
case 'PLAYTEST':
$sxml = simplexml_load_string($request->get('xml'));
if (isset($sxml->tasks->task)) {
foreach ($sxml->tasks->task as $sxtask) {
$ret['tasks'][] = $job->calcSQL($app, $sxtask, true);
$ret = [
'error' => null,
'tasks' => []
];
try {
$job = new RecordsActionsWorker($app);
switch ($request->get('ACT')) {
case 'PLAYTEST':
case 'CALCTEST':
case 'CALCSQL':
$sxml = simplexml_load_string($request->get('xml'));
if ((string)$sxml['version'] !== '2') {
throw new JsonValidationException(sprintf("bad settings version (%s), should be \"2\"", (string)$sxml['version']));
}
}
break;
case 'CALCTEST':
case 'CALCSQL':
$sxml = simplexml_load_string($request->get('xml'));
if (isset($sxml->tasks->task)) {
foreach ($sxml->tasks->task as $sxtask) {
$ret['tasks'][] = $job->calcSQL($app, $sxtask, false);
if (isset($sxml->tasks->task)) {
foreach ($sxml->tasks->task as $sxtask) {
$ret['tasks'][] = $job->calcSQL($sxtask, $request->get('ACT') === 'PLAYTEST');
}
}
}
break;
default:
throw new NotFoundHttpException('Route not found.');
break;
default:
throw new NotFoundHttpException('Route not found.');
}
}
catch (Exception $e) {
$ret['error'] = $e->getMessage();
}

return $app->json($ret);
Expand All @@ -557,73 +563,134 @@ private function getDefaultRecordsActionsSettings()
-->
<tasks>
<comment> keep offline (sb4 = 1) all docs before their "go online" date and after credate (record column) </comment>
<!-- SANITY CHECK ON DOCUMENT SIZE workflow
<task active="0" name="stay offline" action="update" databoxId="1">
<from>
<date direction="before" field="GO_ONLINE"/>
<date direction="after" field="#credate" />
</from>
<to>
<status mask="x1xxxx"/>
</to>
- trash records with documents > 10Mo
-->
<!-- trash jpeg files > 10Mo -->
<task active="0" name="reject too big files " action="update" databoxId="db_databox1">
<if>
<number field="#filesize" compare=">" value="10485760" />
</if>
<then>
<coll id="_TRASH_" />
</then>
</task>
<comment> Put online (sb4 = 0) all docs from 'public' collection and between the online date and the date of archiving </comment>
<task active="0" name="go online" action="update" databoxId="1">
<from>
<comment> 5, 6, 7 are "public" collections </comment>
<coll compare="=" id="5,6,7"/>
<date direction="after" field="GO_ONLINE"/>
<date direction="before" field="TO_ARCHIVE"/>
</from>
<to>
<status mask="x0xxxx"/>
</to>
<!-- EXPIRATION workflow
from "test" collection :
- records having Source = "internal" will expire after 1 month
- other records will expire after 10 days
- records go to "Public" collection
- we want a "last days" status-bit to be set 2 days before expiration
- Expired documents from "Public" collection will go to trash
-->
<!-- set the ExpireDate to (create + 1 month) for source="internal, go public -->
<task active="0" name="compute expiring date for internal" action="update" databoxId="db_databox1">
<if>
<coll compare="=" id="test" />
<text field="Source" compare="=" value="internal" />
<is_unset field="ExpireDate" />
</if>
<then>
<compute_date direction="after" field="#credate" delta="+1 month" computed="exp" />
<set_field field="ExpireDate" value="$exp" />
<coll id="Public" />
</then>
</task>
<!-- set the ExpireDate to (create + 10 days) for others -->
<task active="0" name="compute expiring date for others" action="update" databoxId="db_databox1">
<if>
<coll compare="=" id="test" />
<text field="Source" compare="!=" value="internal" />
<is_unset field="ExpireDate" />
</if>
<then>
<compute_date direction="after" field="#credate" delta="+10 days" computed="exp" />
<set_field field="ExpireDate" value="$exp" />
<coll id="Public" />
</then>
</task>
<comment> Warn 10 days before archiving (raise sb5) </comment>
<!-- if set the "last days" sb 2 days before expiration-->
<task active="0" name="will expire in 2 days" action="update" databoxId="db_databox1">
<if>
<date direction="after" field="ExpireDate" delta="-2 days" />
</if>
<then>
<status mask="1xxxxxx"/>
</then>
</task>
<task active="0" name="almost the end" action="update" databoxId="1">
<from>
<coll compare="=" id="5,6,7"/>
<date direction="after" field="TO_ARCHIVE" delta="-10"/>
</from>
<to>
<status mask="1xxxxx"/>
</to>
<!-- if Public, move to trash after expiration -->
<task active="0" name="expire" action="update" databoxId="db_databox1">
<if>
<coll compare="=" id="Public" />
<date direction="after" field="ExpireDate" />
</if>
<then>
<coll id="_TRASH_" />
</then>
</task>
<comment> Move to 'archive' collection </comment>
<task active="0" name="archivage" action="update" databoxId="1">
<from>
<coll compare="=" id="5,6,7"/>
<date direction="after" field="TO_ARCHIVE" />
</from>
<to>
<comment> reset status of archived documents </comment>
<status mask="00xxxx"/>
<comment> 666 is the "archive" collection </comment>
<coll id="666" />
</to>
<!-- EMPTY TRASH workflow -->
<task active="0" name="clean trash" action="delete" databoxId="db_databox1">
<!-- Delete the records that are in the trash collection, unmodified from 3 months -->
<if>
<coll compare="=" id="_TRASH_"/>
<date direction="after" field="#moddate" delta="+3 months" />
</if>
</task>
<comment> Delete the documents that are in the trash collection unmodified from 3 months </comment>
<task active="0" name="trash" action="delete" databoxId="1">
<from>
<coll compare="=" id="666"/>
<date direction="after" field="#moddate" delta="+90" />
</from>
<!-- SANITY CHECK ON FIELDS workflow
we want a status to show if "Title" and "Description" are filled
-->
<!-- set sb "caption filled" (sb4=1) when both title and Description are set -->
<task active="0" name="Title and Description set" action="update" databoxId="db_databox1">
<if>
<is_set field="Title"/>
<is_set field="Description"/>
</if>
<then>
<status mask="1xxxx"/>
</then>
</task>
</tasks>
<!-- reset sb "caption filled" (sb4=0) when title is not set -->
<task active="0" name="Title not set" action="update" databoxId="db_databox1">
<if>
<is_unset field="Title"/>
</if>
<then>
<status mask="0xxxx"/>
</then>
</task>
<!-- reset sb "caption filled" (sb4=0) when caption is not set -->
<task active="0" name="Description not set" action="update" databoxId="db_databox1">
<if>
<is_unset field="Description"/>
</if>
<then>
<status mask="0xxxx"/>
</then>
</task>
</tasks>
</tasksettings>
EOF;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Alchemy\Phrasea\WorkerManager\Worker\AssetsIngestWorker;
use Alchemy\Phrasea\WorkerManager\Worker\CreateRecordWorker;
use Alchemy\Phrasea\WorkerManager\Worker\DeleteRecordWorker;
use Alchemy\Phrasea\WorkerManager\Worker\EditRecordWorker;
use Alchemy\Phrasea\WorkerManager\Worker\ExportMailWorker;
use Alchemy\Phrasea\WorkerManager\Worker\ExposeUploadWorker;
use Alchemy\Phrasea\WorkerManager\Worker\Factory\CallableWorkerFactory;
Expand All @@ -17,8 +18,7 @@
use Alchemy\Phrasea\WorkerManager\Worker\PopulateIndexWorker;
use Alchemy\Phrasea\WorkerManager\Worker\ProcessPool;
use Alchemy\Phrasea\WorkerManager\Worker\PullAssetsWorker;
use Alchemy\Phrasea\WorkerManager\Worker\EditRecordWorker;
use Alchemy\Phrasea\WorkerManager\Worker\RecordsActionsWorker;
use Alchemy\Phrasea\WorkerManager\Worker\RecordsActionsWorker\RecordsActionsWorker;
use Alchemy\Phrasea\WorkerManager\Worker\Resolver\TypeBasedWorkerResolver;
use Alchemy\Phrasea\WorkerManager\Worker\ShareBasketWorker;
use Alchemy\Phrasea\WorkerManager\Worker\SubdefCreationWorker;
Expand All @@ -27,7 +27,6 @@
use Alchemy\Phrasea\WorkerManager\Worker\WebhookWorker;
use Alchemy\Phrasea\WorkerManager\Worker\WorkerInvoker;
use Alchemy\Phrasea\WorkerManager\Worker\WriteMetadatasWorker;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use Psr\Log\LoggerAwareInterface;
Expand Down
Loading

0 comments on commit 74757ca

Please sign in to comment.