Merge branch 'master' into PHRAS-3116_prod_video-tools-add_subtitle_generation

This commit is contained in:
Harrys Ravalomanana
2020-06-11 19:27:56 +04:00
committed by GitHub
25 changed files with 2540 additions and 1830 deletions

2
.env
View File

@@ -2,7 +2,7 @@ PHRASEANET_PROJECT_NAME=Phraseanet
# Registry from where you pull Docker images
PHRASEANET_DOCKER_REGISTRY=local
# Tag of the Docker images
PHRASEANET_DOCKER_TAG=latest
PHRASEANET_DOCKER_TAG=4.1.1
# APPLICATION PORT
PHRASEANET_APP_PORT=8082
# RabbitMQ configuration

View File

@@ -1,5 +1,155 @@
# CHANGELOG
## 4.1.1
### Change summary
- Phraseanet now using Docker. Retrieve all official images on DockerHub
- Worker manager, a new way for all operations on assets. In the near future, this will replace the current task manager.
- Geolocation based on Mapbox (requires an account on Mapbox https://www.mapbox.com).
- Video chaptering and subtitling support.
- GUI redesign for Push, Feedback, List manager, Lightbox on mobile.
this version is finale version of 4.1.0 published in preview at start of year, a lot of improvement, bugfixes on several elements see summary here
### New Feature summary
* [PHRAS-2023] - Refacto Lightbox mobile in 4.1
* [PHRAS-2219] - Refacto design Push screen
* [PHRAS-2220] - Refacto design Feedback screen
* [PHRAS-2221] - Refacto design List manager general screen
* [PHRAS-2222] - Refacto design ListManager Advance Mode screen
* [PHRAS-2223] - Refacto dev list manager Advance Mode screen
* [PHRAS-2541] - Dev-Design-Prod/Publish Screen
* [PHRAS-2548] - Phraseanet Docker and Docker Compose
* [PHRAS-1226] - Geolocalisation In Phraseanet
* [PHRAS-1626] - bin/console databox:mount mount an existing databox
* [PHRAS-1628] - bin/console collection:publish
* [PHRAS-1630] - bin/console database:unmout
* [PHRAS-1631] - bin/console collection:unpublish
* [PHRAS-1648] - bin/console user:password
* [PHRAS-1659] - bin/console user:create
* [PHRAS-1771] - bin/console collection:unpublish
* [PHRAS-1773] - bin/console collection:publish
* [PHRAS-2518] - Phraseanet worker Read/Write metadata
* [PHRAS-2520] - Phraseanet worker send webhook
* [PHRAS-2738] - Phraseanet worker populate database
* [PHRAS-2435] - Phraseanet Worker Build subdefinition
* [PHRAS-2436] - Phraseanet Worker build zip export and send mail
* [PHRAS-2636] - Phraseanet Worker fetch assets from external uploader (pull mode)
* [PHRAS-2904] - Fullfill field define in geoloc - position field with information return by Geonames
* [PHRAS-161] - PROD Add a maps for geolocalisation of media in detailed view
* [PHRAS-1935] - View prod/ Video chapter editor
* [PHRAS-2997] - Matomo analytic service in Phraseanet
* [PHRAS-1890] - Add GS1 databases model to Phraseanet
### Improvement and fix summary
* [PHRAS-1561] - Prod | Print - Use the label of field when print, use the GUI user language
* [PHRAS-2067] - Prod : Introduce thumbnail & preview generic images for Fonts records
* [PHRAS-2473] - Populate Optimisation, sometime populate databox (database) is very long
* [PHRAS-2524] - Put worker log in ELK
* [PHRAS-2739] - incorporate Phraseanet-plugin-SubdefWebhook into Phraseanet
* [PHRAS-2157] - Prod / Share : Iframe sizes are set to 0 for audio documents
* [PHRAS-2538] - Some MP4 file is not correctly detected by Phraseanet.
* [PHRAS-2825] - Prod : Add a reset button to initialize searches filters
* [PHRAS-1872] - prod/export by email / subject are NOK
* [PHRAS-2342] - Report : collections not selected
* [PHRAS-2343] - report : all fields of all databases
* [PHRAS-2350] - Report : url is too long
* [PHRAS-2476] - Bad header in generated video preview file
* [PHRAS-2196] - API - Stories records pagination on search answer and Stories fetch info
* [PHRAS-2880] - extend admin GUI for define facets ordering.
* [PHRAS-2967] - Lightbox - dev of send email report - warn windows
* [PHRAS-1752] - update facebook sdk dependency
* [PHRAS-2678] - add `webhook monitor`
* [PHRAS-2915] - Lightbox (desktop version) Change sort order for basket and Feedback in landing page ( most recent in first)
* [PHRAS-2082] - Bump design of windows create user , create template user, create new subdef
* [PHRAS-2676] - Weaked download behaviour for large amount of data
* [PHRAS-2671] - Change behavior of preview display in audio file case
* [PHRAS-2879] - Define facets order in GUI and query result
## 4.0.12
Release notes - Phraseanet - Version 4.0.12
### Improvement
* [PHRAS-2955] - Cache doctrine entity metadata for performance
* [PHRAS-2964] - Application-box - set host colon of table sbas set to char 255
* [PHRAS-3012] - [PHRAS-2977] - Docker compose optimisation, refacto volumes, build image
optimisation, add Phraseanet plugin in build image, bump ffmpeg version in worker,
fix error un redis configuration.
more option for define volumes during installation process.
* [PHRAS-3027] - Backport To 4.0 - Populate - Slow query - due to LIMIT in sql query.
* [PHRAS-3027] - Translation improvement in EN and DE.
### Bugfix
* [PHRAS-2979] - The content of a story is not displayed even for users with appropriate on the collection
## 4.1.0
Pre release of 4.1
## 4.0.11
Release notes - Phraseanet - Version 4.0.11
### New Feature and Improvement
* [PHRAS-2878] - Print feedback report in PDF
* [PHRAS-2757] - Exclude some collections from quarantine checkers sha256, UUID, filename (AKA exclude Trash from quarantine)
* [PHRAS-2766] - Add status change capabilities to quarantine lazaret in substitute and add action
* [PHRAS-2674] - Prod grey skin Improvement
* [PHRAS-2775] - Prod - plugin - Publish item in diapo local menu - plugin skeleton improvement.
* [PHRAS-925] - Search Engine improvement for word with dot and hyphen characters
* [PHRAS-2496] - Pre-build vagrant image for Phraseanet and implement it in Phraseanet vagrant file.
* [PHRAS-2637] - Sub definition Task init : select all databases when databases property is not set
* [PHRAS-2670] - Fix notifications slow sql and basket select
* [PHRAS-2672] - Bump videojs version to 7.5
* [PHRAS-2691] - Prod - delete from trash , send deletion by bulk of 3 records
* [PHRAS-2700] - Prod - number of results - Formating the results number
* [PHRAS-2742] - Enhance plugin-skeleton in 4.0
* [PHRAS-2750] - PHPExiftool to handle DJI XMP Tags, Bump exiftool version and switch to original exiftool/exiftool github repository
* [PHRAS-835] - ES - date format timestamp unix, store and search datetime
* [PHRAS-2791] - Embed-bundle - Videojs player serve poster-image property with sub definition permalink
* [PHRAS-2842] - Databases Models - now default audio encodeur is mp3lame
* [PHRAS-2857] - Exclude some collections from quarantine checkers sha256, UUID, filename (AKA exclude Trash)
* [PHRAS-2899] - Quarantine: allow to substitute without selecting target record, (when match only one record).
* [PHRAS-2765] - Translation in Plugin menu locale is now available
* [PHRAS-2929] - bump sinonjs dependency to 1.7.1
* [PHRAS-2728] - Landing page take browser language in account
* [PHRAS-2693] - Collection Sort Sorter is now presented by column
* [PHRAS-2817] - Deploy and Dev with docker is OK
### Bugfix
* [PHRAS-1069] - Dates seems not extracted from iptc
* [PHRAS-1428] - Phraseanet Binaries in configuration not used in some alchemy-fr libraries (AKA text extraction of pdf is NOK)
* [PHRAS-2567] - Registration Form - Term of use link is broken
* [PHRAS-2644] - Searching for stories after applying a document filtering choice gives no results
* [PHRAS-2652] - Fields "Phraseanet::no-source" are pushed to exiftool
* [PHRAS-2682] - Prod - facets display is NOK when switch from basket or thesaurus Tab.
* [PHRAS-2695] - Prod - Grey and White Skins - Browse Baskets: Unable to read the titles
* [PHRAS-2702] - Lightbox - scroller thumbnail Nok
* [PHRAS-2714] - Adding record from the API leaves a copy of the file into the system temporary directory
* [PHRAS-2715] - Embed bundle, border issue on firefox.
* [PHRAS-2716] - Records SetStatus HTTP API malfunction
* [PHRAS-2723] - None information (name, last name etc...) is keep from the Push or a FeedBack user creation form
* [PHRAS-2748] - Some characters into cterms (candidats) leeds to 500 error
* [PHRAS-2754] - Permalink is not (re) activated when record is move from _TRASH_ collection
* [PHRAS-2860] - Generated Subdefs for video Portait are not correctly Oriented
* [PHRAS-2877] - User manipulator does not allow to set a null email
* [PHRAS-2912] - When updating a user informations the wrong field are populated (job and activity inverted)
* [PHRAS-2811] - Cleanning of bad chars in candidats terms
## 4.0.10
Not publish
## 4.0.9
### Adds
@@ -13,11 +163,11 @@
### Fixes
* PHRAS-2491 - Front - Click on facets title (expand/collapse) launched a bad query, due to jquery error.
* PHRAS-2510 - Front - Facets values appear Truncated after 15th character.
* PHRAS-2153 - Front - No user search possible with the field "Company" and field "Country".
* PHRAS-2154 - Front - Bug on Chrome only - selected 1 document instead of all for the feedback.
* PHRAS-2538 - Back - Some MP4 files were not correctly detected by Phraseanet.
- PHRAS-2491 - Front - Click on facets title (expand/collapse) launched a bad query, due to jquery error.
- PHRAS-2510 - Front - Facets values appear Truncated after 15th character.
- PHRAS-2153 - Front - No user search possible with the field "Company" and field "Country".
- PHRAS-2154 - Front - Bug on Chrome only - selected 1 document instead of all for the feedback.
- PHRAS-2538 - Back - Some MP4 files were not correctly detected by Phraseanet.
## 4.0.8

View File

@@ -67,6 +67,7 @@ RUN echo "deb http://deb.debian.org/debian stretch main non-free" > /etc/apt/sou
libgsm1-dev \
libfreetype6-dev \
# End FFmpeg
nano \
&& update-locale "LANG=fr_FR.UTF-8 UTF-8" \
&& dpkg-reconfigure --frontend noninteractive locales \
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \

View File

@@ -32,7 +32,7 @@ And follow the install steps described at https://docs.phraseanet.com/4.0/en/Adm
## Prerequisites
- docker-compose
- docker-compose >=v1.25.4
- docker >=v18.01-ce
## Get started
@@ -100,6 +100,12 @@ https://hub.docker.com/r/alchemyfr/phraseanet-worker
https://hub.docker.com/r/alchemyfr/phraseanet-nginx
https://hub.docker.com/repository/docker/alchemyfr/phraseanet-db
https://hub.docker.com/repository/docker/alchemyfr/phraseanet-elasticsearch
To use them and not build the images locally, we advise to override the properties in file: env.local
```bash
@@ -108,6 +114,21 @@ PHRASEANET_DOCKER_REGISTRY=alchemyfr
# Tag of the Docker images
PHRASEANET_DOCKER_TAG=
```
or
Pull images before launch docker-compose
#### Tag organisation on docker hub
```latest``` : latest stable version
```4.0``` : latest stable version in 4.0
```4.1``` : latest stable version in 4.1
```4.1.1``` : Phraseanet version 4.1.1
## Development mode

View File

@@ -19,8 +19,10 @@ FILE=config/configuration.yml
if [ -f "$FILE" ]; then
echo "$FILE exists, skip setup."
if [[ $PHRASEANET_PROJECT_NAME ]]; then
bin/setup system:config set registry.general.title $PHRASEANET_PROJECT_NAME
if [[ $PHRASEANET_SMTP_ENABLED=true ]]; then
fi
if [[ $PHRASEANET_SMTP_ENABLED && $PHRASEANET_SMTP_ENABLED=true ]]; then
bin/setup system:config set registry.email.smtp-enabled $PHRASEANET_SMTP_ENABLED
bin/setup system:config set registry.email.smtp-auth-enabled $PHRASEANET_SMTP_AUTH_ENABLED
bin/setup system:config set registry.email.smtp-auth-secure-mode $PHRASEANET_SMTP_SECURE_MODE
@@ -31,7 +33,10 @@ if [ -f "$FILE" ]; then
bin/setup system:config set registry.email.emitter-email $PHRASEANET_EMITTER_EMAIL
bin/setup system:config set registry.email.prefix $PHRASEANET_MAIL_OBJECT_PREFIX
fi
if [[ $PHRASEANET_ADMIN_ACCOUNT_PASSWORD ]]; then
bin/console user:password --user_id=1 --password $PHRASEANET_ADMIN_ACCOUNT_PASSWORD -y
fi
else
echo "$FILE doesn't exist, entering setup..."
runuser app -c docker/phraseanet/auto-install.sh

View File

@@ -17,7 +17,7 @@ class Version
* @var string
*/
private $number = '4.1.0-alpha.29a';
private $number = '4.1.1';
/**
* @var string

View File

@@ -20,6 +20,8 @@ class WorkerRunningJob
const FINISHED = 'finished';
const RUNNING = 'running';
const MAX_RESULT = 500;
/**
* @ORM\Column(type="integer")
* @ORM\Id

View File

@@ -23,9 +23,9 @@ class WorkerExecuteCommand extends Command
$this->setDescription('Listen queues define on configuration, launch corresponding service for execution')
->addOption('preserve-payload', 'p', InputOption::VALUE_NONE, 'Preserve temporary payload file')
->addOption('queue-name', '', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'The name of queues to be consuming')
->addOption('max-processes', 'm', InputOption::VALUE_REQUIRED, 'The max number of process allow to run (default 4) ')
->addOption('MWG', '', InputOption::VALUE_NONE, 'Enable MWG metadata compatibility (use only for write metadata service)')
->addOption('clear-metadatas', '', InputOption::VALUE_NONE, 'Delete metadatas from documents if not compliant with Database structure (use only for write metadata service)')
->addOption('max-processes', 'm', InputOption::VALUE_REQUIRED, 'The max number of process allow to run (default 1) ')
// ->addOption('MWG', '', InputOption::VALUE_NONE, 'Enable MWG metadata compatibility (use only for write metadata service)')
// ->addOption('clear-metadatas', '', InputOption::VALUE_NONE, 'Remove metadatas from documents if not compliant with Database structure (use only for write metadata service)')
->setHelp('');
return $this;
@@ -33,9 +33,6 @@ class WorkerExecuteCommand extends Command
protected function doExecute(InputInterface $input, OutputInterface $output)
{
$MWG = false;
$clearMetadatas = false;
$argQueueName = $input->getOption('queue-name');
$maxProcesses = intval($input->getOption('max-processes'));
@@ -64,14 +61,6 @@ class WorkerExecuteCommand extends Command
$workerInvoker->setMaxProcessPoolValue($maxProcesses);
}
if ($input->getOption('MWG')) {
$MWG = true;
}
if ($input->getOption('clear-metadatas')) {
$clearMetadatas = true;
}
if ($input->getOption('preserve-payload')) {
$workerInvoker->preservePayloads();
}

View File

@@ -79,11 +79,11 @@ class AdminConfigurationController extends Controller
$reload = ($request->query->get('reload')) == 1 ? true : false ;
if ($request->query->get('running') == 1 && $request->query->get('finished') == 1) {
$workerRunningJob = $repoWorker->findAll();
$workerRunningJob = $repoWorker->findBy([], ['id' => 'DESC'], WorkerRunningJob::MAX_RESULT);
} elseif ($request->query->get('running') == 1) {
$workerRunningJob = $repoWorker->findBy(['status' => WorkerRunningJob::RUNNING]);
$workerRunningJob = $repoWorker->findBy(['status' => WorkerRunningJob::RUNNING], ['id' => 'DESC'], WorkerRunningJob::MAX_RESULT);
} elseif ($request->query->get('finished') == 1) {
$workerRunningJob = $repoWorker->findBy(['status' => WorkerRunningJob::FINISHED]);
$workerRunningJob = $repoWorker->findBy(['status' => WorkerRunningJob::FINISHED], ['id' => 'DESC'], WorkerRunningJob::MAX_RESULT);
}
return $this->render('admin/worker-manager/worker_info.html.twig', [
@@ -92,6 +92,22 @@ class AdminConfigurationController extends Controller
]);
}
public function queueMonitorAction(PhraseaApplication $app, Request $request)
{
$reload = ($request->query->get('reload')) == 1 ? true : false ;
/** @var AMQPConnection $serverConnection */
$serverConnection = $app['alchemy_worker.amqp.connection'];
$serverConnection->getChannel();
$serverConnection->declareExchange();
$queuesStatus = $serverConnection->getQueuesStatus();
return $this->render('admin/worker-manager/worker_queue_monitor.html.twig', [
'queuesStatus' => $queuesStatus,
'reload' => $reload
]);
}
public function truncateTableAction(PhraseaApplication $app, Request $request)
{
/** @var WorkerRunningJobRepository $repoWorker */

View File

@@ -84,6 +84,10 @@ class ControllerServiceProvider implements ControllerProviderInterface, ServiceP
->method('GET|POST')
->bind('worker_admin_pullAssets');
$controllers->match('/queue-monitor', 'controller.worker.admin.configuration:queueMonitorAction')
->method('GET')
->bind('worker_admin_queue_monitor');
return $controllers;
}

View File

@@ -213,6 +213,37 @@ class AMQPConnection
}
}
/**
* Get queueName, messageCount, consumerCount of queues
* @return array
*/
public function getQueuesStatus()
{
$queuesList = array_merge(
array_values(self::$defaultQueues),
array_values(self::$defaultDelayedQueues),
array_values(self::$defaultRetryQueues),
array_values(self::$defaultFailedQueues)
);
$this->getChannel();
$queuesStatus = [];
foreach ($queuesList as $queue) {
$this->setQueue($queue);
list($queueName, $messageCount, $consumerCount) = $this->channel->queue_declare($queue, true);
$status['queueName'] = $queueName;
$status['messageCount'] = $messageCount;
$status['consumerCount'] = $consumerCount;
$queuesStatus[] = $status;
unset($status);
}
return $queuesStatus;
}
public function connectionClose()
{
$this->channel->close();

View File

@@ -10,7 +10,7 @@ use Symfony\Component\Process\ProcessBuilder;
class ProcessPool implements LoggerAwareInterface
{
const MAX_PROCESSES = 4;
const MAX_PROCESSES = 1;
/**
* @var int
@@ -41,7 +41,7 @@ class ProcessPool implements LoggerAwareInterface
* Sets a logger instance on the object
*
* @param LoggerInterface $logger
* @return null
* @return void
*/
public function setLogger(LoggerInterface $logger)
{

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
<file date="2020-06-05T14:10:58Z" source-language="en" target-language="de" datatype="plaintext" original="not.available">
<file date="2020-06-11T06:48:12Z" source-language="en" target-language="de" datatype="plaintext" original="not.available">
<header>
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/>
<note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>
@@ -9,9 +9,9 @@
<trans-unit id="96f0767cb7ea65a7f86c8c9432e80d16cf9d8680" resname="Please provide the same passwords." approved="yes">
<source>Please provide the same passwords.</source>
<target state="translated">Bitte geben Sie diesselbe Passwörter ein.</target>
<jms:reference-file line="49">Form/Login/PhraseaRegisterForm.php</jms:reference-file>
<jms:reference-file line="36">Form/Login/PhraseaRenewPasswordForm.php</jms:reference-file>
<jms:reference-file line="44">Form/Login/PhraseaRecoverPasswordForm.php</jms:reference-file>
<jms:reference-file line="49">Form/Login/PhraseaRegisterForm.php</jms:reference-file>
</trans-unit>
<trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore" approved="yes">
<source>The token provided is not valid anymore</source>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
<file date="2020-06-05T14:11:24Z" source-language="en" target-language="en" datatype="plaintext" original="not.available">
<file date="2020-06-11T06:50:35Z" source-language="en" target-language="en" datatype="plaintext" original="not.available">
<header>
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/>
<note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>
@@ -9,9 +9,9 @@
<trans-unit id="96f0767cb7ea65a7f86c8c9432e80d16cf9d8680" resname="Please provide the same passwords." approved="yes">
<source>Please provide the same passwords.</source>
<target state="translated">Please provide the same passwords.</target>
<jms:reference-file line="49">Form/Login/PhraseaRegisterForm.php</jms:reference-file>
<jms:reference-file line="36">Form/Login/PhraseaRenewPasswordForm.php</jms:reference-file>
<jms:reference-file line="44">Form/Login/PhraseaRecoverPasswordForm.php</jms:reference-file>
<jms:reference-file line="49">Form/Login/PhraseaRegisterForm.php</jms:reference-file>
</trans-unit>
<trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore" approved="yes">
<source>The token provided is not valid anymore</source>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
<file date="2020-06-05T14:11:52Z" source-language="en" target-language="fr" datatype="plaintext" original="not.available">
<file date="2020-06-11T06:53:27Z" source-language="en" target-language="fr" datatype="plaintext" original="not.available">
<header>
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/>
<note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>
@@ -9,9 +9,9 @@
<trans-unit id="96f0767cb7ea65a7f86c8c9432e80d16cf9d8680" resname="Please provide the same passwords." approved="yes">
<source>Please provide the same passwords.</source>
<target state="translated">Veuillez indiquer des mots de passe identiques.</target>
<jms:reference-file line="49">Form/Login/PhraseaRegisterForm.php</jms:reference-file>
<jms:reference-file line="36">Form/Login/PhraseaRenewPasswordForm.php</jms:reference-file>
<jms:reference-file line="44">Form/Login/PhraseaRecoverPasswordForm.php</jms:reference-file>
<jms:reference-file line="49">Form/Login/PhraseaRegisterForm.php</jms:reference-file>
</trans-unit>
<trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore" approved="yes">
<source>The token provided is not valid anymore</source>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
<file date="2020-06-05T14:12:23Z" source-language="en" target-language="nl" datatype="plaintext" original="not.available">
<file date="2020-06-11T06:55:24Z" source-language="en" target-language="nl" datatype="plaintext" original="not.available">
<header>
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/>
<note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>
@@ -9,9 +9,9 @@
<trans-unit id="96f0767cb7ea65a7f86c8c9432e80d16cf9d8680" resname="Please provide the same passwords.">
<source>Please provide the same passwords.</source>
<target state="new">Please provide the same passwords.</target>
<jms:reference-file line="49">Form/Login/PhraseaRegisterForm.php</jms:reference-file>
<jms:reference-file line="36">Form/Login/PhraseaRenewPasswordForm.php</jms:reference-file>
<jms:reference-file line="44">Form/Login/PhraseaRecoverPasswordForm.php</jms:reference-file>
<jms:reference-file line="49">Form/Login/PhraseaRegisterForm.php</jms:reference-file>
</trans-unit>
<trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore">
<source>The token provided is not valid anymore</source>

View File

@@ -0,0 +1,345 @@
<?php
namespace Alchemy\Phrasea\Model\Proxies\__CG__\Alchemy\Phrasea\Model\Entities;
/**
* DO NOT EDIT THIS FILE - IT WAS CREATED BY DOCTRINE'S PROXY GENERATOR
*/
class WorkerRunningJob extends \Alchemy\Phrasea\Model\Entities\WorkerRunningJob implements \Doctrine\ORM\Proxy\Proxy
{
/**
* @var \Closure the callback responsible for loading properties in the proxy object. This callback is called with
* three parameters, being respectively the proxy object to be initialized, the method that triggered the
* initialization process and an array of ordered parameters that were passed to that method.
*
* @see \Doctrine\Common\Persistence\Proxy::__setInitializer
*/
public $__initializer__;
/**
* @var \Closure the callback responsible of loading properties that need to be copied in the cloned object
*
* @see \Doctrine\Common\Persistence\Proxy::__setCloner
*/
public $__cloner__;
/**
* @var boolean flag indicating if this object was already initialized
*
* @see \Doctrine\Common\Persistence\Proxy::__isInitialized
*/
public $__isInitialized__ = false;
/**
* @var array properties to be lazy loaded, with keys being the property
* names and values being their default values
*
* @see \Doctrine\Common\Persistence\Proxy::__getLazyProperties
*/
public static $lazyPropertiesDefaults = [];
/**
* @param \Closure $initializer
* @param \Closure $cloner
*/
public function __construct($initializer = null, $cloner = null)
{
$this->__initializer__ = $initializer;
$this->__cloner__ = $cloner;
}
/**
*
* @return array
*/
public function __sleep()
{
if ($this->__isInitialized__) {
return ['__isInitialized__', '' . "\0" . 'Alchemy\\Phrasea\\Model\\Entities\\WorkerRunningJob' . "\0" . 'id', '' . "\0" . 'Alchemy\\Phrasea\\Model\\Entities\\WorkerRunningJob' . "\0" . 'databoxId', '' . "\0" . 'Alchemy\\Phrasea\\Model\\Entities\\WorkerRunningJob' . "\0" . 'recordId', '' . "\0" . 'Alchemy\\Phrasea\\Model\\Entities\\WorkerRunningJob' . "\0" . 'work', '' . "\0" . 'Alchemy\\Phrasea\\Model\\Entities\\WorkerRunningJob' . "\0" . 'workOn', '' . "\0" . 'Alchemy\\Phrasea\\Model\\Entities\\WorkerRunningJob' . "\0" . 'created', '' . "\0" . 'Alchemy\\Phrasea\\Model\\Entities\\WorkerRunningJob' . "\0" . 'published', '' . "\0" . 'Alchemy\\Phrasea\\Model\\Entities\\WorkerRunningJob' . "\0" . 'status'];
}
return ['__isInitialized__', '' . "\0" . 'Alchemy\\Phrasea\\Model\\Entities\\WorkerRunningJob' . "\0" . 'id', '' . "\0" . 'Alchemy\\Phrasea\\Model\\Entities\\WorkerRunningJob' . "\0" . 'databoxId', '' . "\0" . 'Alchemy\\Phrasea\\Model\\Entities\\WorkerRunningJob' . "\0" . 'recordId', '' . "\0" . 'Alchemy\\Phrasea\\Model\\Entities\\WorkerRunningJob' . "\0" . 'work', '' . "\0" . 'Alchemy\\Phrasea\\Model\\Entities\\WorkerRunningJob' . "\0" . 'workOn', '' . "\0" . 'Alchemy\\Phrasea\\Model\\Entities\\WorkerRunningJob' . "\0" . 'created', '' . "\0" . 'Alchemy\\Phrasea\\Model\\Entities\\WorkerRunningJob' . "\0" . 'published', '' . "\0" . 'Alchemy\\Phrasea\\Model\\Entities\\WorkerRunningJob' . "\0" . 'status'];
}
/**
*
*/
public function __wakeup()
{
if ( ! $this->__isInitialized__) {
$this->__initializer__ = function (WorkerRunningJob $proxy) {
$proxy->__setInitializer(null);
$proxy->__setCloner(null);
$existingProperties = get_object_vars($proxy);
foreach ($proxy->__getLazyProperties() as $property => $defaultValue) {
if ( ! array_key_exists($property, $existingProperties)) {
$proxy->$property = $defaultValue;
}
}
};
}
}
/**
*
*/
public function __clone()
{
$this->__cloner__ && $this->__cloner__->__invoke($this, '__clone', []);
}
/**
* Forces initialization of the proxy
*/
public function __load()
{
$this->__initializer__ && $this->__initializer__->__invoke($this, '__load', []);
}
/**
* {@inheritDoc}
* @internal generated method: use only when explicitly handling proxy specific loading logic
*/
public function __isInitialized()
{
return $this->__isInitialized__;
}
/**
* {@inheritDoc}
* @internal generated method: use only when explicitly handling proxy specific loading logic
*/
public function __setInitialized($initialized)
{
$this->__isInitialized__ = $initialized;
}
/**
* {@inheritDoc}
* @internal generated method: use only when explicitly handling proxy specific loading logic
*/
public function __setInitializer(\Closure $initializer = null)
{
$this->__initializer__ = $initializer;
}
/**
* {@inheritDoc}
* @internal generated method: use only when explicitly handling proxy specific loading logic
*/
public function __getInitializer()
{
return $this->__initializer__;
}
/**
* {@inheritDoc}
* @internal generated method: use only when explicitly handling proxy specific loading logic
*/
public function __setCloner(\Closure $cloner = null)
{
$this->__cloner__ = $cloner;
}
/**
* {@inheritDoc}
* @internal generated method: use only when explicitly handling proxy specific cloning logic
*/
public function __getCloner()
{
return $this->__cloner__;
}
/**
* {@inheritDoc}
* @internal generated method: use only when explicitly handling proxy specific loading logic
* @static
*/
public function __getLazyProperties()
{
return self::$lazyPropertiesDefaults;
}
/**
* {@inheritDoc}
*/
public function getId()
{
if ($this->__isInitialized__ === false) {
return (int) parent::getId();
}
$this->__initializer__ && $this->__initializer__->__invoke($this, 'getId', []);
return parent::getId();
}
/**
* {@inheritDoc}
*/
public function setDataboxId($databoxId)
{
$this->__initializer__ && $this->__initializer__->__invoke($this, 'setDataboxId', [$databoxId]);
return parent::setDataboxId($databoxId);
}
/**
* {@inheritDoc}
*/
public function getDataboxId()
{
$this->__initializer__ && $this->__initializer__->__invoke($this, 'getDataboxId', []);
return parent::getDataboxId();
}
/**
* {@inheritDoc}
*/
public function setRecordId($recordId)
{
$this->__initializer__ && $this->__initializer__->__invoke($this, 'setRecordId', [$recordId]);
return parent::setRecordId($recordId);
}
/**
* {@inheritDoc}
*/
public function getRecordId()
{
$this->__initializer__ && $this->__initializer__->__invoke($this, 'getRecordId', []);
return parent::getRecordId();
}
/**
* {@inheritDoc}
*/
public function setWork($work)
{
$this->__initializer__ && $this->__initializer__->__invoke($this, 'setWork', [$work]);
return parent::setWork($work);
}
/**
* {@inheritDoc}
*/
public function getWork()
{
$this->__initializer__ && $this->__initializer__->__invoke($this, 'getWork', []);
return parent::getWork();
}
/**
* {@inheritDoc}
*/
public function setWorkOn($workOn)
{
$this->__initializer__ && $this->__initializer__->__invoke($this, 'setWorkOn', [$workOn]);
return parent::setWorkOn($workOn);
}
/**
* {@inheritDoc}
*/
public function getWorkOn()
{
$this->__initializer__ && $this->__initializer__->__invoke($this, 'getWorkOn', []);
return parent::getWorkOn();
}
/**
* {@inheritDoc}
*/
public function getCreated()
{
$this->__initializer__ && $this->__initializer__->__invoke($this, 'getCreated', []);
return parent::getCreated();
}
/**
* {@inheritDoc}
*/
public function setPublished(\DateTime $published)
{
$this->__initializer__ && $this->__initializer__->__invoke($this, 'setPublished', [$published]);
return parent::setPublished($published);
}
/**
* {@inheritDoc}
*/
public function getPublished()
{
$this->__initializer__ && $this->__initializer__->__invoke($this, 'getPublished', []);
return parent::getPublished();
}
/**
* {@inheritDoc}
*/
public function setStatus($status)
{
$this->__initializer__ && $this->__initializer__->__invoke($this, 'setStatus', [$status]);
return parent::setStatus($status);
}
/**
* {@inheritDoc}
*/
public function getStatus()
{
$this->__initializer__ && $this->__initializer__->__invoke($this, 'getStatus', []);
return parent::getStatus();
}
/**
* {@inheritDoc}
*/
public function getWorkName()
{
$this->__initializer__ && $this->__initializer__->__invoke($this, 'getWorkName', []);
return parent::getWorkName();
}
}

View File

@@ -35,6 +35,11 @@
{{ 'admin::workermanager:tab:metadata: title' |trans }}
</a>
</li>
<li class="worker-queue-monitor" role="presentation">
<a href="#worker-queue-monitor" aria-controls="worker-queue-monitor" role="tab" data-toggle="tab" data-url="/admin/worker-manager/queue-monitor">
{{ 'admin::workermanager:tab:queueMonitor: title' |trans }}
</a>
</li>
</ul>
@@ -48,6 +53,7 @@
<div role="tabpanel" class="tab-pane fade" id="worker-pull-assets"></div>
<div role="tabpanel" class="tab-pane fade" id="worker-subview"></div>
<div role="tabpanel" class="tab-pane fade" id="worker-metadata"></div>
<div role="tabpanel" class="tab-pane fade" id="worker-queue-monitor"></div>
</div>
</div>

View File

@@ -42,7 +42,7 @@
<table class="admintable">
<thead>
<tr>
<th class="sortable">{{ 'admin::workermanager:tab:workerinfo: databox_id' | trans }}</th>
<th class="sortable">{{ 'admin::workermanager:tab:workerinfo: databox_name' | trans }}</th>
<th class="sortable">{{ 'admin::workermanager:tab:workerinfo: record_id' | trans }}</th>
<th class="sortable">{{ 'admin::workermanager:tab:workerinfo: work' | trans }}</th>
<th class="sortable">{{ 'admin::workermanager:tab:workerinfo: work_on' | trans }}</th>
@@ -57,7 +57,7 @@
{% for workerRow in workerRunningJob | sort | reverse %}
<tr>
<td>{{ workerRow.databoxId }}</td>
<td>{{ workerRow.databoxId | sbas_labels(app) }}</td>
<td>{{ workerRow.recordId }}</td>
<td>{{ workerRow.getWorkName }}</td>
<td>{{ workerRow.workOn }}</td>

View File

@@ -0,0 +1,42 @@
{% if not reload %}
<h1>{{ 'admin::workermanager:tab:queueMonitor: description' |trans }}</h1>
<button id="refresh-monitor" class="btn btn-success">
{{ 'admin::workermanager:tab:queueMonitor: Refresh list' |trans }}
</button>
<table class="admintable">
<thead>
<tr>
<th></th>
<th>{{ 'admin::workermanager:tab:queueMonitor: Message count' |trans }}</th>
<th>{{ 'admin::workermanager:tab:queueMonitor: Consumer count' |trans }}</th>
</tr>
</thead>
<tbody class="queue-list">
{% endif %}
{% for queueStatus in queuesStatus %}
<tr>
<th>{{ queueStatus.queueName }}</th>
<td>{{ queueStatus.messageCount }}</td>
<td>{{ queueStatus.consumerCount }}</td>
</tr>
{% endfor %}
{% if not reload %}
</tbody>
</table>
<script type="text/javascript">
$("#refresh-monitor").on('click', function () {
$.ajax({
type: "GET",
url: "/admin/worker-manager/queue-monitor?reload=1",
success: function (data) {
$(".queue-list").empty().html(data);
}
});
});
</script>
{% endif %}

View File

@@ -232,7 +232,7 @@
{% endif %}
</li>
<li>
<a target="_blank" href="https://docs.phraseanet.com/4.0/">
<a target="_blank" href="{{ 'https://docs.phraseanet.com/4.1/' ~ app['locale'] }}">
<span>
{{ 'phraseanet:: aide' | trans }}
</span>