Merge branch 'master' into PHRAS-3097_prod-editing-preview-video

This commit is contained in:
Nicolas Maillat
2020-05-27 22:41:06 +02:00
committed by GitHub
36 changed files with 2964 additions and 2302 deletions

View File

@@ -313,6 +313,7 @@ geocoding-providers:
- '2.335062' - '2.335062'
default-zoom: 5 default-zoom: 5
marker-default-zoom: 9 marker-default-zoom: 9
position-fields: []
geonames-field-mapping: true geonames-field-mapping: true
cityfields: City, Ville cityfields: City, Ville
provincefields: Province provincefields: Province
@@ -330,3 +331,5 @@ workers:
user_account: user_account:
deleting_policies: deleting_policies:
email_confirmation: true email_confirmation: true
Console_logger_enabled_environments: [test]

View File

@@ -181,19 +181,14 @@ class RegistryFormManipulator
], ],
'custom-links' => [ 'custom-links' => [
[ [
'linkName' => 'Phraseanet store', 'linkName' => 'Phraseanet store',
'linkLanguage' => 'fr', 'linkLanguage' => 'all',
'linkUrl' => 'https://alchemy.odoo.com/shop', 'linkUrl' => 'https://store.alchemy.fr',
'linkLocation' => 'help-menu', 'linkLocation' => 'help-menu',
'linkOrder' => '1', 'linkOrder' => 1,
], 'linkBold' => false,
[ 'linkColor' => ''
'linkName' => 'Phraseanet store', ]
'linkLanguage' => 'en',
'linkUrl' => 'https://alchemy.odoo.com/en_US/shop',
'linkLocation' => 'help-menu',
'linkOrder' => '1',
],
] ]
]; ];
} }

View File

@@ -150,6 +150,12 @@ class RepositoriesServiceProvider implements ServiceProviderInterface
$app['repo.worker-running-job'] = $app->share(function (PhraseaApplication $app) { $app['repo.worker-running-job'] = $app->share(function (PhraseaApplication $app) {
return $app['orm.em']->getRepository('Phraseanet:WorkerRunningJob'); return $app['orm.em']->getRepository('Phraseanet:WorkerRunningJob');
}); });
$app['repo.worker-running-populate'] = $app->share(function (PhraseaApplication $app) {
return $app['orm.em']->getRepository('Phraseanet:WorkerRunningPopulate');
});
$app['repo.worker-running-uploader'] = $app->share(function (PhraseaApplication $app) {
return $app['orm.em']->getRepository('Phraseanet:WorkerRunningUploader');
});
$app['repo.databoxes'] = $app->share(function (PhraseaApplication $app) { $app['repo.databoxes'] = $app->share(function (PhraseaApplication $app) {
$appbox = $app->getApplicationBox(); $appbox = $app->getApplicationBox();

View File

@@ -16,8 +16,8 @@ class Version
/** /**
* @var string * @var string
*/ */
private $number = '4.1.0-alpha.27a'; private $number = '4.1.0-alpha.29a';
/** /**
* @var string * @var string

View File

@@ -59,6 +59,11 @@ class WorkerRunningJob
*/ */
private $published; private $published;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $finished;
/** /**
* @ORM\Column(type="string", name="status") * @ORM\Column(type="string", name="status")
*/ */
@@ -179,6 +184,25 @@ class WorkerRunningJob
return $this->published; return $this->published;
} }
/**
* @param \DateTime $finished
* @return $this
*/
public function setFinished(\DateTime $finished)
{
$this->finished = $finished;
return $this;
}
/**
* @return mixed
*/
public function getFinished()
{
return $this->finished;
}
/** /**
* @param $status * @param $status
* @return $this * @return $this

View File

@@ -0,0 +1,219 @@
<?php
namespace Alchemy\Phrasea\Model\Entities;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* @ORM\Table(name="WorkerRunningPopulate",
* indexes={
* @ORM\index(name="host", columns={"host"}),
* @ORM\index(name="port", columns={"port"}),
* @ORM\index(name="index_name", columns={"index_name"}),
* }
* )
* @ORM\Entity(repositoryClass="Alchemy\Phrasea\Model\Repositories\WorkerRunningPopulateRepository")
*/
class WorkerRunningPopulate
{
const FINISHED = 'finished';
const RUNNING = 'running';
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
private $id;
/**
* @ORM\Column(type="string", name="host")
*/
private $host;
/**
* @ORM\Column(type="string", name="port")
*/
private $port;
/**
* @ORM\Column(type="string", name="index_name")
*/
private $indexName;
/**
* @ORM\Column(type="integer", name="databox_id")
*/
private $databoxId;
/**
* @Gedmo\Timestampable(on="create")
* @ORM\Column(type="datetime")
*/
private $created;
/**
* @ORM\Column(type="datetime")
*/
private $published;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $finished;
/**
* @ORM\Column(type="string", name="status")
*/
private $status;
/**
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* @param $host
* @return $this
*/
public function setHost($host)
{
$this->host = $host;
return $this;
}
/**
* @return mixed
*/
public function getHost()
{
return $this->host;
}
/**
* @param $port
* @return $this
*/
public function setPort($port)
{
$this->port = $port;
return $this;
}
/**
* @return mixed
*/
public function getPort()
{
return $this->port;
}
/**
* @param $indexName
* @return $this
*/
public function setIndexName($indexName)
{
$this->indexName = $indexName;
return $this;
}
/**
* @return mixed
*/
public function getIndexName()
{
return $this->indexName;
}
/**
* @param $databoxId
* @return $this
*/
public function setDataboxId($databoxId)
{
$this->databoxId = $databoxId;
return $this;
}
/**
* @return mixed
*/
public function getDataboxId()
{
return $this->databoxId;
}
/**
* @return \DateTime
*/
public function getCreated()
{
return $this->created;
}
/**
* @param \DateTime $published
* @return $this
*/
public function setPublished(\DateTime $published)
{
$this->published = $published;
return $this;
}
/**
* @return mixed
*/
public function getPublished()
{
return $this->published;
}
/**
* @param \DateTime $finished
* @return $this
*/
public function setFinished(\DateTime $finished)
{
$this->finished = $finished;
return $this;
}
/**
* @return mixed
*/
public function getFinished()
{
return $this->finished;
}
/**
* @param $status
* @return $this
*/
public function setStatus($status)
{
$this->status = $status;
return $this;
}
/**
* @return mixed
*/
public function getStatus()
{
return $this->status;
}
}

View File

@@ -0,0 +1,198 @@
<?php
namespace Alchemy\Phrasea\Model\Entities;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* @ORM\Table(name="WorkerRunningUploader",
* indexes={
* @ORM\index(name="commit_id", columns={"commit_id"}),
* @ORM\index(name="asset_id", columns={"asset_id"}),
* }
* )
* @ORM\Entity(repositoryClass="Alchemy\Phrasea\Model\Repositories\WorkerRunningUploaderRepository")
*/
class WorkerRunningUploader
{
const DOWNLOADED = 'downloaded';
const RUNNING = 'running';
const TYPE_PULL = 'pull';
const TYPE_PUSH = 'push';
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
private $id;
/**
* @ORM\Column(type="string", name="commit_id")
*/
private $commitId;
/**
* @ORM\Column(type="string", name="asset_id")
*/
private $assetId;
/**
* @ORM\Column(type="string", name="type")
*/
private $type;
/**
* @Gedmo\Timestampable(on="create")
* @ORM\Column(type="datetime")
*/
private $created;
/**
* @ORM\Column(type="datetime")
*/
private $published;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $finished;
/**
* @ORM\Column(type="string", name="status")
*/
private $status;
/**
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* @param $commitId
* @return $this
*/
public function setCommitId($commitId)
{
$this->commitId = $commitId;
return $this;
}
/**
* @return mixed
*/
public function getCommitId()
{
return $this->commitId;
}
/**
* @param $assetId
* @return $this
*/
public function setAssetId($assetId)
{
$this->assetId = $assetId;
return $this;
}
/**
* @return mixed
*/
public function getAssetId()
{
return $this->assetId;
}
/**
* @return \DateTime
*/
public function getCreated()
{
return $this->created;
}
/**
* @param \DateTime $published
* @return $this
*/
public function setPublished(\DateTime $published)
{
$this->published = $published;
return $this;
}
/**
* @return mixed
*/
public function getPublished()
{
return $this->published;
}
/**
* @param \DateTime $finished
* @return $this
*/
public function setFinished(\DateTime $finished)
{
$this->finished = $finished;
return $this;
}
/**
* @return mixed
*/
public function getFinished()
{
return $this->finished;
}
/**
* @param $status
* @return $this
*/
public function setStatus($status)
{
$this->status = $status;
return $this;
}
/**
* @return mixed
*/
public function getStatus()
{
return $this->status;
}
/**
* @param $type
* @return $this
*/
public function setType($type)
{
$this->type = $type;
return $this;
}
/**
* @return mixed
*/
public function getType()
{
return $this->type;
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Alchemy\Phrasea\Model\Repositories;
use Alchemy\Phrasea\Model\Entities\WorkerRunningPopulate;
use Doctrine\ORM\EntityRepository;
class WorkerRunningPopulateRepository extends EntityRepository
{
public function getEntityManager()
{
return parent::getEntityManager();
}
/**
* @param array $databoxIds
* @return int
*/
public function checkPopulateStatusByDataboxIds(array $databoxIds)
{
$qb = $this->createQueryBuilder('w');
$qb->where($qb->expr()->in('w.databoxId', $databoxIds))
->andWhere('w.status = :status')
->setParameter('status', WorkerRunningPopulate::RUNNING)
;
return count($qb->getQuery()->getResult());
}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace Alchemy\Phrasea\Model\Repositories;
use Alchemy\Phrasea\Model\Entities\WorkerRunningUploader;
use Doctrine\ORM\EntityRepository;
class WorkerRunningUploaderRepository extends EntityRepository
{
public function getEntityManager()
{
return parent::getEntityManager();
}
/**
* @param $commitId
* @return bool
*/
public function canAck($commitId)
{
$qb = $this->createQueryBuilder('w');
$res = $qb
->where('w.commitId = :commitId')
->andWhere('w.status != :status')
->setParameters([
'commitId' => $commitId,
'status' => WorkerRunningUploader::DOWNLOADED
])
->getQuery()
->getResult()
;
return count($res) == 0;
}
}

View File

@@ -198,7 +198,7 @@ class Installer
$config['main']['database']['driver'] = 'pdo_mysql'; $config['main']['database']['driver'] = 'pdo_mysql';
$config['main']['database']['charset'] = 'UTF8'; $config['main']['database']['charset'] = 'UTF8';
$config['main']['binaries'] = $binaryData; $config['main']['binaries'] = array_merge($config['main']['binaries'], $binaryData);
$config['servername'] = $serverName; $config['servername'] = $serverName;
$config['main']['key'] = $this->app['random.medium']->generateString(16); $config['main']['key'] = $this->app['random.medium']->generateString(16);

View File

@@ -1,33 +0,0 @@
<?php
namespace Alchemy\Phrasea\WorkerManager\Configuration;
class Config
{
const WORKER_DATABASE_FILE = 'worker.db';
public static function getPluginDatabaseFile()
{
$dbDir = realpath(dirname(__FILE__) . "/../") . "/Db" ;
if (!is_dir($dbDir)) {
mkdir($dbDir, 0755, true);
}
$dbFile = $dbDir . '/' . self::WORKER_DATABASE_FILE;
if (!is_file($dbFile)) {
file_put_contents($dbFile, '');
}
return $dbFile;
}
public static function getWorkerSqliteConnection()
{
$db_conn = 'sqlite:'. self::getPluginDatabaseFile();
$pdo = new \PDO($db_conn);
return $pdo;
}
}

View File

@@ -6,13 +6,13 @@ use Alchemy\Phrasea\Application as PhraseaApplication;
use Alchemy\Phrasea\Controller\Controller; use Alchemy\Phrasea\Controller\Controller;
use Alchemy\Phrasea\Model\Entities\WorkerRunningJob; use Alchemy\Phrasea\Model\Entities\WorkerRunningJob;
use Alchemy\Phrasea\Model\Repositories\WorkerRunningJobRepository; use Alchemy\Phrasea\Model\Repositories\WorkerRunningJobRepository;
use Alchemy\Phrasea\Model\Repositories\WorkerRunningPopulateRepository;
use Alchemy\Phrasea\SearchEngine\Elastic\ElasticsearchOptions; use Alchemy\Phrasea\SearchEngine\Elastic\ElasticsearchOptions;
use Alchemy\Phrasea\WorkerManager\Event\PopulateIndexEvent; use Alchemy\Phrasea\WorkerManager\Event\PopulateIndexEvent;
use Alchemy\Phrasea\WorkerManager\Event\WorkerEvents; use Alchemy\Phrasea\WorkerManager\Event\WorkerEvents;
use Alchemy\Phrasea\WorkerManager\Form\WorkerConfigurationType; use Alchemy\Phrasea\WorkerManager\Form\WorkerConfigurationType;
use Alchemy\Phrasea\WorkerManager\Form\WorkerPullAssetsType; use Alchemy\Phrasea\WorkerManager\Form\WorkerPullAssetsType;
use Alchemy\Phrasea\WorkerManager\Form\WorkerSearchengineType; use Alchemy\Phrasea\WorkerManager\Form\WorkerSearchengineType;
use Alchemy\Phrasea\WorkerManager\Model\DBManipulator;
use Alchemy\Phrasea\WorkerManager\Queue\AMQPConnection; use Alchemy\Phrasea\WorkerManager\Queue\AMQPConnection;
use Alchemy\Phrasea\WorkerManager\Queue\MessagePublisher; use Alchemy\Phrasea\WorkerManager\Queue\MessagePublisher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface;
@@ -147,7 +147,10 @@ class AdminConfigurationController extends Controller
{ {
$databoxIds = $request->get('sbasIds'); $databoxIds = $request->get('sbasIds');
return DBManipulator::checkPopulateIndexStatusByDataboxId($databoxIds); /** @var WorkerRunningPopulateRepository $repoWorkerPopulate */
$repoWorkerPopulate = $app['repo.worker-running-populate'];
return $repoWorkerPopulate->checkPopulateStatusByDataboxIds($databoxIds);
} }
public function pullAssetsAction(PhraseaApplication $app, Request $request) public function pullAssetsAction(PhraseaApplication $app, Request $request)

View File

@@ -1,175 +0,0 @@
<?php
namespace Alchemy\Phrasea\WorkerManager\Model;
use Alchemy\Phrasea\WorkerManager\Configuration\Config;
class DBManipulator
{
/**
* @param array $params = [host, port, indexName, databoxId]
*/
public static function savePopulateStatus(array $params)
{
$pdo = Config::getWorkerSqliteConnection();
$pdo->beginTransaction();
try {
$pdo->query("CREATE TABLE IF NOT EXISTS populate_running(host TEXT NOT NULL, port TEXT NOT NULL, index_name TEXT NOT NULL, databox_id TEXT NOT NULL);");
$stmt = $pdo->prepare("INSERT INTO populate_running(host, port, index_name, databox_id) VALUES(:host, :port, :index_name, :databox_id)");
$stmt->execute([
':host' => $params['host'],
':port' => $params['port'],
':index_name' => $params['indexName'],
':databox_id' => $params['databoxId']
]);
$pdo->commit();
} catch (\Exception $e) {
$pdo->rollBack();
}
}
/**
* @param array $params = [host, port, indexName, databoxId]
*/
public static function deletePopulateStatus(array $params)
{
$pdo = Config::getWorkerSqliteConnection();
$pdo->beginTransaction();
try {
$stmt = $pdo->prepare("DELETE FROM populate_running WHERE host = :host AND port= :port AND index_name= :index_name AND databox_id= :databox_id");
$stmt->execute([
':host' => $params['host'],
':port' => $params['port'],
':index_name' => $params['indexName'],
':databox_id' => $params['databoxId']
]);
$pdo->commit();
} catch (\Exception $e) {
$pdo->rollBack();
}
}
/**
* Update commits table in the temporary sqlite worker.db
* @param $commitId
* @param $assetId
* @return int the number of the remaining assets in the commit
*/
public static function updateRemainingAssetsListByCommit($commitId, $assetId)
{
$row = 1;
$pdo = Config::getWorkerSqliteConnection();
$pdo->beginTransaction();
try {
// remove assetId from the assets list
$stmt = $pdo->prepare("DELETE FROM commits WHERE commit_id = :commit_id AND asset= :assetId");
$stmt->execute([
':commit_id' => $commitId,
':assetId' => $assetId
]);
$stmt = $pdo->prepare("SELECT * FROM commits WHERE commit_id = :commit_id");
$stmt->execute([
':commit_id' => $commitId,
]);
$row = $stmt->fetchAll(\PDO::FETCH_ASSOC);
$pdo->commit();
} catch (\Exception $e) {
$pdo->rollBack();
}
return count($row);
}
/**
* @param $commitId
* @return bool
*/
public static function isCommitToBeCreating($commitId)
{
$pdo = Config::getWorkerSqliteConnection();
$pdo->beginTransaction();
$row = 0;
try {
$pdo->query("CREATE TABLE IF NOT EXISTS commits(commit_id TEXT NOT NULL, asset TEXT NOT NULL);");
$stmt = $pdo->prepare("SELECT * FROM commits WHERE commit_id = :commit_id");
$stmt->execute([
':commit_id' => $commitId,
]);
$row = $stmt->fetchAll(\PDO::FETCH_ASSOC);
$pdo->commit();
} catch (\Exception $e) {
//no-op
}
return count($row) ? true : false;
}
public static function saveAssetsList($commitId, $assetIds)
{
$pdo = Config::getWorkerSqliteConnection();
$pdo->beginTransaction();
try {
$pdo->query("CREATE TABLE IF NOT EXISTS commits(commit_id TEXT NOT NULL, asset TEXT NOT NULL);");
// insert all assets ID in the temporary sqlite database
foreach ($assetIds as $assetId) {
$stmt = $pdo->prepare("INSERT INTO commits(commit_id, asset) VALUES(:commit_id, :asset)");
$stmt->execute([
':commit_id' => $commitId,
':asset' => $assetId
]);
}
$pdo->commit();
} catch (\Exception $e) {
$pdo->rollBack();
}
}
/**
* @param array $databoxIds
* @return int
*/
public static function checkPopulateIndexStatusByDataboxId(array $databoxIds)
{
$pdo = Config::getWorkerSqliteConnection();
$in = str_repeat("?,", count($databoxIds)-1) . "?";
$pdo->beginTransaction();
try {
$pdo->query("CREATE TABLE IF NOT EXISTS populate_running(host TEXT NOT NULL, port TEXT NOT NULL, index_name TEXT NOT NULL, databox_id TEXT NOT NULL);");
$stmt = $pdo->prepare("SELECT * FROM populate_running WHERE databox_id IN ($in)");
$stmt->execute($databoxIds);
$row = $stmt->fetchAll(\PDO::FETCH_ASSOC);
$pdo->commit();
} catch (\Exception $e) {
$pdo->rollBack();
}
return count($row);
}
}

View File

@@ -115,13 +115,13 @@ class AlchemyWorkerServiceProvider implements PluginProviderInterface
})); }));
$app['alchemy_worker.type_based_worker_resolver']->addFactory(MessagePublisher::POPULATE_INDEX_TYPE, new CallableWorkerFactory(function () use ($app) { $app['alchemy_worker.type_based_worker_resolver']->addFactory(MessagePublisher::POPULATE_INDEX_TYPE, new CallableWorkerFactory(function () use ($app) {
return (new PopulateIndexWorker($app['alchemy_worker.message.publisher'], $app['elasticsearch.indexer'])) return (new PopulateIndexWorker($app['alchemy_worker.message.publisher'], $app['elasticsearch.indexer'], $app['repo.worker-running-populate']))
->setApplicationBox($app['phraseanet.appbox']) ->setApplicationBox($app['phraseanet.appbox'])
->setDispatcher($app['dispatcher']); ->setDispatcher($app['dispatcher']);
})); }));
$app['alchemy_worker.type_based_worker_resolver']->addFactory(MessagePublisher::PULL_ASSETS_TYPE, new CallableWorkerFactory(function () use ($app) { $app['alchemy_worker.type_based_worker_resolver']->addFactory(MessagePublisher::PULL_ASSETS_TYPE, new CallableWorkerFactory(function () use ($app) {
return new PullAssetsWorker($app['alchemy_worker.message.publisher'], $app['conf']); return new PullAssetsWorker($app['alchemy_worker.message.publisher'], $app['conf'], $app['repo.worker-running-uploader']);
})); }));
$app['alchemy_worker.type_based_worker_resolver']->addFactory(MessagePublisher::DELETE_RECORD_TYPE, new CallableWorkerFactory(function () use ($app) { $app['alchemy_worker.type_based_worker_resolver']->addFactory(MessagePublisher::DELETE_RECORD_TYPE, new CallableWorkerFactory(function () use ($app) {

View File

@@ -2,6 +2,7 @@
namespace Alchemy\Phrasea\WorkerManager\Subscriber; namespace Alchemy\Phrasea\WorkerManager\Subscriber;
use Alchemy\Phrasea\Model\Entities\WorkerRunningUploader;
use Alchemy\Phrasea\WorkerManager\Event\AssetsCreateEvent; use Alchemy\Phrasea\WorkerManager\Event\AssetsCreateEvent;
use Alchemy\Phrasea\WorkerManager\Event\AssetsCreationFailureEvent; use Alchemy\Phrasea\WorkerManager\Event\AssetsCreationFailureEvent;
use Alchemy\Phrasea\WorkerManager\Event\AssetsCreationRecordFailureEvent; use Alchemy\Phrasea\WorkerManager\Event\AssetsCreationRecordFailureEvent;
@@ -21,11 +22,13 @@ class AssetsIngestSubscriber implements EventSubscriberInterface
public function onAssetsCreate(AssetsCreateEvent $event) public function onAssetsCreate(AssetsCreateEvent $event)
{ {
// this is an uploader PUSH mode
$payload = [ $payload = [
'message_type' => MessagePublisher::ASSETS_INGEST_TYPE, 'message_type' => MessagePublisher::ASSETS_INGEST_TYPE,
'payload' => $event->getData() 'payload' => array_merge($event->getData(), ['type' => WorkerRunningUploader::TYPE_PUSH])
]; ];
$this->messagePublisher->publishMessage($payload, MessagePublisher::ASSETS_INGEST_QUEUE); $this->messagePublisher->publishMessage($payload, MessagePublisher::ASSETS_INGEST_QUEUE);
} }

View File

@@ -5,10 +5,11 @@ namespace Alchemy\Phrasea\WorkerManager\Worker;
use Alchemy\Phrasea\Application\Helper\EntityManagerAware; use Alchemy\Phrasea\Application\Helper\EntityManagerAware;
use Alchemy\Phrasea\Application as PhraseaApplication; use Alchemy\Phrasea\Application as PhraseaApplication;
use Alchemy\Phrasea\Model\Entities\StoryWZ; use Alchemy\Phrasea\Model\Entities\StoryWZ;
use Alchemy\Phrasea\Model\Entities\WorkerRunningUploader;
use Alchemy\Phrasea\Model\Repositories\UserRepository; use Alchemy\Phrasea\Model\Repositories\UserRepository;
use Alchemy\Phrasea\Model\Repositories\WorkerRunningUploaderRepository;
use Alchemy\Phrasea\WorkerManager\Event\AssetsCreationFailureEvent; use Alchemy\Phrasea\WorkerManager\Event\AssetsCreationFailureEvent;
use Alchemy\Phrasea\WorkerManager\Event\WorkerEvents; use Alchemy\Phrasea\WorkerManager\Event\WorkerEvents;
use Alchemy\Phrasea\WorkerManager\Model\DBManipulator;
use Alchemy\Phrasea\WorkerManager\Queue\MessagePublisher; use Alchemy\Phrasea\WorkerManager\Queue\MessagePublisher;
use GuzzleHttp\Client; use GuzzleHttp\Client;
@@ -21,6 +22,9 @@ class AssetsIngestWorker implements WorkerInterface
/** @var MessagePublisher $messagePublisher */ /** @var MessagePublisher $messagePublisher */
private $messagePublisher; private $messagePublisher;
/** @var WorkerRunningUploaderRepository $repoWorkerUploader */
private $repoWorkerUploader;
public function __construct(PhraseaApplication $app) public function __construct(PhraseaApplication $app)
{ {
$this->app = $app; $this->app = $app;
@@ -30,8 +34,9 @@ class AssetsIngestWorker implements WorkerInterface
public function process(array $payload) public function process(array $payload)
{ {
$assets = $payload['assets']; $assets = $payload['assets'];
$this->repoWorkerUploader = $this->getWorkerRunningUploaderRepository();
DBManipulator::saveAssetsList($payload['commit_id'], $assets); $this->saveAssetsList($payload['commit_id'], $assets, $payload['published'], $payload['type']);
$uploaderClient = new Client(['base_uri' => $payload['base_url']]); $uploaderClient = new Client(['base_uri' => $payload['base_url']]);
@@ -120,4 +125,42 @@ class AssetsIngestWorker implements WorkerInterface
{ {
return $this->app['repo.users']; return $this->app['repo.users'];
} }
/**
* @return WorkerRunningUploaderRepository
*/
private function getWorkerRunningUploaderRepository()
{
return $this->app['repo.worker-running-uploader'];
}
private function saveAssetsList($commitId, $assetsId, $published, $type)
{
$em = $this->repoWorkerUploader->getEntityManager();
$em->beginTransaction();
$date = new \DateTime();
try {
foreach ($assetsId as $assetId) {
$workerRunningUploader = new WorkerRunningUploader();
$workerRunningUploader
->setCommitId($commitId)
->setAssetId($assetId)
->setPublished($date->setTimestamp($published))
->setStatus(WorkerRunningUploader::RUNNING)
->setType($type)
;
$em->persist($workerRunningUploader);
unset($workerRunningUploader);
}
$em->flush();
$em->commit();
} catch(\Exception $e) {
$em->rollback();
}
}
} }

View File

@@ -19,10 +19,11 @@ use Alchemy\Phrasea\Media\SubdefSubstituer;
use Alchemy\Phrasea\Model\Entities\LazaretFile; use Alchemy\Phrasea\Model\Entities\LazaretFile;
use Alchemy\Phrasea\Model\Entities\LazaretSession; use Alchemy\Phrasea\Model\Entities\LazaretSession;
use Alchemy\Phrasea\Model\Entities\User; use Alchemy\Phrasea\Model\Entities\User;
use Alchemy\Phrasea\Model\Entities\WorkerRunningUploader;
use Alchemy\Phrasea\Model\Repositories\UserRepository; use Alchemy\Phrasea\Model\Repositories\UserRepository;
use Alchemy\Phrasea\Model\Repositories\WorkerRunningUploaderRepository;
use Alchemy\Phrasea\WorkerManager\Event\AssetsCreationRecordFailureEvent; use Alchemy\Phrasea\WorkerManager\Event\AssetsCreationRecordFailureEvent;
use Alchemy\Phrasea\WorkerManager\Event\WorkerEvents; use Alchemy\Phrasea\WorkerManager\Event\WorkerEvents;
use Alchemy\Phrasea\WorkerManager\Model\DBManipulator;
use Alchemy\Phrasea\WorkerManager\Queue\MessagePublisher; use Alchemy\Phrasea\WorkerManager\Queue\MessagePublisher;
use GuzzleHttp\Client; use GuzzleHttp\Client;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
@@ -41,6 +42,9 @@ class CreateRecordWorker implements WorkerInterface
/** @var MessagePublisher $messagePublisher */ /** @var MessagePublisher $messagePublisher */
private $messagePublisher; private $messagePublisher;
/** @var WorkerRunningUploaderRepository $repoWorkerUploader */
private $repoWorkerUploader;
public function __construct(PhraseaApplication $app) public function __construct(PhraseaApplication $app)
{ {
$this->app = $app; $this->app = $app;
@@ -50,6 +54,9 @@ class CreateRecordWorker implements WorkerInterface
public function process(array $payload) public function process(array $payload)
{ {
$this->repoWorkerUploader = $this->getWorkerRunningUploaderRepository();
$em = $this->repoWorkerUploader->getEntityManager();
$uploaderClient = new Client(['base_uri' => $payload['base_url']]); $uploaderClient = new Client(['base_uri' => $payload['base_url']]);
//get asset informations //get asset informations
@@ -63,6 +70,13 @@ class CreateRecordWorker implements WorkerInterface
$tempfile = $this->getTemporaryFilesystem()->createTemporaryFile('download_', null, pathinfo($body['originalName'], PATHINFO_EXTENSION)); $tempfile = $this->getTemporaryFilesystem()->createTemporaryFile('download_', null, pathinfo($body['originalName'], PATHINFO_EXTENSION));
/** @var WorkerRunningUploader $workerRunningUploader */
$workerRunningUploader = $this->repoWorkerUploader->findOneBy([
'commitId' => $payload['commit_id'],
'assetId' => $payload['asset']
]);
//download the asset //download the asset
try { try {
$res = $uploaderClient->get('/assets/'.$payload['asset'].'/download', [ $res = $uploaderClient->get('/assets/'.$payload['asset'].'/download', [
@@ -81,6 +95,9 @@ class CreateRecordWorker implements WorkerInterface
$count $count
)); ));
$em->remove($workerRunningUploader);
$em->flush();
return; return;
} }
@@ -98,13 +115,31 @@ class CreateRecordWorker implements WorkerInterface
$count $count
)); ));
$em->remove($workerRunningUploader);
$em->flush();
return; return;
} }
$remainingAssets = DBManipulator::updateRemainingAssetsListByCommit($payload['commit_id'], $payload['asset']); if ($workerRunningUploader != null) {
$em->beginTransaction();
try {
$workerRunningUploader->setStatus(WorkerRunningUploader::DOWNLOADED);
$em->persist($workerRunningUploader);
$em->flush();
$em->commit();
} catch (\Exception $e) {
$em->rollback();
}
}
$canAck = $this->repoWorkerUploader->canAck($payload['commit_id']);
// if all assets in the commit are downloaded , send ack to the uploader // if all assets in the commit are downloaded , send ack to the uploader
if ($remainingAssets == 0) { if ($canAck) {
// post ack to the uploader // post ack to the uploader
$uploaderClient->post('/commits/' . $payload['commit_id'] . '/ack', [ $uploaderClient->post('/commits/' . $payload['commit_id'] . '/ack', [
'headers' => [ 'headers' => [
@@ -300,4 +335,12 @@ class CreateRecordWorker implements WorkerInterface
{ {
return $this->app['subdef.substituer']; return $this->app['subdef.substituer'];
} }
/**
* @return WorkerRunningUploaderRepository
*/
private function getWorkerRunningUploaderRepository()
{
return $this->app['repo.worker-running-uploader'];
}
} }

View File

@@ -4,11 +4,12 @@ namespace Alchemy\Phrasea\WorkerManager\Worker;
use Alchemy\Phrasea\Application\Helper\ApplicationBoxAware; use Alchemy\Phrasea\Application\Helper\ApplicationBoxAware;
use Alchemy\Phrasea\Application\Helper\DispatcherAware; use Alchemy\Phrasea\Application\Helper\DispatcherAware;
use Alchemy\Phrasea\Model\Entities\WorkerRunningPopulate;
use Alchemy\Phrasea\Model\Repositories\WorkerRunningPopulateRepository;
use Alchemy\Phrasea\SearchEngine\Elastic\ElasticsearchOptions; use Alchemy\Phrasea\SearchEngine\Elastic\ElasticsearchOptions;
use Alchemy\Phrasea\SearchEngine\Elastic\Indexer; use Alchemy\Phrasea\SearchEngine\Elastic\Indexer;
use Alchemy\Phrasea\WorkerManager\Event\PopulateIndexFailureEvent; use Alchemy\Phrasea\WorkerManager\Event\PopulateIndexFailureEvent;
use Alchemy\Phrasea\WorkerManager\Event\WorkerEvents; use Alchemy\Phrasea\WorkerManager\Event\WorkerEvents;
use Alchemy\Phrasea\WorkerManager\Model\DBManipulator;
use Alchemy\Phrasea\WorkerManager\Queue\MessagePublisher; use Alchemy\Phrasea\WorkerManager\Queue\MessagePublisher;
class PopulateIndexWorker implements WorkerInterface class PopulateIndexWorker implements WorkerInterface
@@ -22,15 +23,41 @@ class PopulateIndexWorker implements WorkerInterface
/** @var Indexer $indexer */ /** @var Indexer $indexer */
private $indexer; private $indexer;
public function __construct(MessagePublisher $messagePublisher, Indexer $indexer) /** @var WorkerRunningPopulateRepository $repoWorkerPopulate*/
private $repoWorkerPopulate;
public function __construct(MessagePublisher $messagePublisher, Indexer $indexer, WorkerRunningPopulateRepository $repoWorkerPopulate)
{ {
$this->indexer = $indexer; $this->indexer = $indexer;
$this->messagePublisher = $messagePublisher; $this->messagePublisher = $messagePublisher;
$this->repoWorkerPopulate = $repoWorkerPopulate;
} }
public function process(array $payload) public function process(array $payload)
{ {
DBManipulator::savePopulateStatus($payload); $em = $this->repoWorkerPopulate->getEntityManager();
$em->beginTransaction();
$date = new \DateTime();
try {
$workerRunningPopulate = new WorkerRunningPopulate();
$workerRunningPopulate
->setHost($payload['host'])
->setPort($payload['port'])
->setIndexName($payload['indexName'])
->setDataboxId($payload['databoxId'])
->setPublished($date->setTimestamp($payload['published']))
->setStatus(WorkerRunningPopulate::RUNNING)
;
$em->persist($workerRunningPopulate);
$em->flush();
$em->commit();
} catch (\Exception $e) {
$em->rollback();
}
/** @var ElasticsearchOptions $options */ /** @var ElasticsearchOptions $options */
$options = $this->indexer->getIndex()->getOptions(); $options = $this->indexer->getIndex()->getOptions();
@@ -71,7 +98,12 @@ class PopulateIndexWorker implements WorkerInterface
$r['memory']/1048576 $r['memory']/1048576
)); ));
} catch(\Exception $e) { } catch(\Exception $e) {
DBManipulator::deletePopulateStatus($payload); if ($workerRunningPopulate != null) {
$em->remove($workerRunningPopulate);
$em->flush();
}
$workerMessage = sprintf("Error on indexing : %s ", $e->getMessage()); $workerMessage = sprintf("Error on indexing : %s ", $e->getMessage());
$this->messagePublisher->pushLog($workerMessage); $this->messagePublisher->pushLog($workerMessage);
@@ -90,8 +122,17 @@ class PopulateIndexWorker implements WorkerInterface
} }
} }
// delete entry in populate_running // tell that the populate is finished
DBManipulator::deletePopulateStatus($payload); if ($workerRunningPopulate != null) {
$workerRunningPopulate
->setStatus(WorkerRunningPopulate::FINISHED)
->setFinished(new \DateTime('now'))
;
$em->persist($workerRunningPopulate);
$em->flush();
}
} }
} }

View File

@@ -3,7 +3,8 @@
namespace Alchemy\Phrasea\WorkerManager\Worker; namespace Alchemy\Phrasea\WorkerManager\Worker;
use Alchemy\Phrasea\Core\Configuration\PropertyAccess; use Alchemy\Phrasea\Core\Configuration\PropertyAccess;
use Alchemy\Phrasea\WorkerManager\Model\DBManipulator; use Alchemy\Phrasea\Model\Entities\WorkerRunningUploader;
use Alchemy\Phrasea\Model\Repositories\WorkerRunningUploaderRepository;
use Alchemy\Phrasea\WorkerManager\Queue\MessagePublisher; use Alchemy\Phrasea\WorkerManager\Queue\MessagePublisher;
use GuzzleHttp\Client; use GuzzleHttp\Client;
@@ -12,10 +13,14 @@ class PullAssetsWorker implements WorkerInterface
private $messagePublisher; private $messagePublisher;
private $conf; private $conf;
public function __construct(MessagePublisher $messagePublisher, PropertyAccess $conf) /** @var WorkerRunningUploaderRepository $repoWorkerUploader */
private $repoWorkerUploader;
public function __construct(MessagePublisher $messagePublisher, PropertyAccess $conf, WorkerRunningUploaderRepository $repoWorkerUploader)
{ {
$this->messagePublisher = $messagePublisher; $this->messagePublisher = $messagePublisher;
$this->conf = $conf; $this->conf = $conf;
$this->repoWorkerUploader = $repoWorkerUploader;
} }
public function process(array $payload) public function process(array $payload)
@@ -62,9 +67,10 @@ class PullAssetsWorker implements WorkerInterface
foreach ($commits as $commit) { foreach ($commits as $commit) {
// send only payload in ingest-queue if the commit is ack false and it is not being creating // send only payload in ingest-queue if the commit is ack false and it is not being creating
if (!$commit['acknowledged'] && !DBManipulator::isCommitToBeCreating($commit['id'])) { if (!$commit['acknowledged'] && !$this->isCommitToBeCreating($commit['id'])) {
$this->messagePublisher->pushLog("A new commit found in the uploader ! commit_ID : ".$commit['id']); $this->messagePublisher->pushLog("A new commit found in the uploader ! commit_ID : ".$commit['id']);
// this is an uploader PULL mode
$payload = [ $payload = [
'message_type' => MessagePublisher::ASSETS_INGEST_TYPE, 'message_type' => MessagePublisher::ASSETS_INGEST_TYPE,
'payload' => [ 'payload' => [
@@ -74,7 +80,8 @@ class PullAssetsWorker implements WorkerInterface
'publisher' => $commit['userId'], 'publisher' => $commit['userId'],
'commit_id' => $commit['id'], 'commit_id' => $commit['id'],
'token' => $commit['token'], 'token' => $commit['token'],
'base_url' => $baseUrl 'base_url' => $baseUrl,
'type' => WorkerRunningUploader::TYPE_PULL
] ]
]; ];
@@ -134,4 +141,15 @@ class PullAssetsWorker implements WorkerInterface
return $this->conf->get(['workers', 'pull_assets']); return $this->conf->get(['workers', 'pull_assets']);
} }
/**
* @param $commitId
* @return bool
*/
private function isCommitToBeCreating($commitId)
{
$res = $this->repoWorkerUploader->findBy(['commitId' => $commitId]);
return count($res) != 0;
}
} }

View File

@@ -75,9 +75,6 @@ class SubdefCreationWorker implements WorkerInterface
'payload' => $payload 'payload' => $payload
]; ];
$this->messagePublisher->publishMessage($payload, MessagePublisher::DELAYED_SUBDEF_QUEUE); $this->messagePublisher->publishMessage($payload, MessagePublisher::DELAYED_SUBDEF_QUEUE);
//
// $message = MessagePublisher::SUBDEF_CREATION_TYPE.' to be re-published! >> Payload ::'. json_encode($payload);
// $this->messagePublisher->pushLog($message);
return ; return ;
} }
@@ -176,6 +173,7 @@ class SubdefCreationWorker implements WorkerInterface
$em->beginTransaction(); $em->beginTransaction();
try { try {
$workerRunningJob->setStatus(WorkerRunningJob::FINISHED); $workerRunningJob->setStatus(WorkerRunningJob::FINISHED);
$workerRunningJob->setFinished(new \DateTime('now'));
$em->persist($workerRunningJob); $em->persist($workerRunningJob);
$em->flush(); $em->flush();
$em->commit(); $em->commit();

View File

@@ -77,9 +77,6 @@ class WriteMetadatasWorker implements WorkerInterface
]; ];
$this->messagePublisher->publishMessage($payload, MessagePublisher::DELAYED_METADATAS_QUEUE); $this->messagePublisher->publishMessage($payload, MessagePublisher::DELAYED_METADATAS_QUEUE);
// $message = MessagePublisher::WRITE_METADATAS_TYPE.' to be re-published! >> Payload ::'. json_encode($payload);
// $this->messagePublisher->pushLog($message);
return ; return ;
} }
@@ -251,6 +248,7 @@ class WriteMetadatasWorker implements WorkerInterface
$em->beginTransaction(); $em->beginTransaction();
try { try {
$workerRunningJob->setStatus(WorkerRunningJob::FINISHED); $workerRunningJob->setStatus(WorkerRunningJob::FINISHED);
$workerRunningJob->setFinished(new \DateTime('now'));
$em->persist($workerRunningJob); $em->persist($workerRunningJob);
$em->flush(); $em->flush();
$em->commit(); $em->commit();

View File

@@ -0,0 +1,174 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2020 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Alchemy\Phrasea\Application;
class patch_410alpha28a implements patchInterface
{
/** @var string */
private $release = '4.1.0-alpha.28a';
/** @var array */
private $concern = [base::APPLICATION_BOX];
/**
* Returns the release version.
*
* @return string
*/
public function get_release()
{
return $this->release;
}
/**
* {@inheritdoc}
*/
public function concern()
{
return $this->concern;
}
/**
* {@inheritdoc}
*/
public function require_all_upgrades()
{
return false;
}
/**
* {@inheritdoc}
*/
public function getDoctrineMigrations()
{
return [];
}
/**
* {@inheritdoc}
*/
public function apply(base $appbox, Application $app)
{
// add geoloc section if not exist
if (!$app['conf']->has(['geocoding-providers'])) {
$providers[0] = [
'map-provider' => 'mapboxWebGL',
'enabled' => false,
'public-key' => '',
'map-layers' => [
0 => [
'name' => 'Light',
'value' => 'mapbox://styles/mapbox/light-v9'
],
1 => [
'name' => 'Streets',
'value' => 'mapbox://styles/mapbox/streets-v9'
],
2 => [
'name' => 'Basic',
'value' => 'mapbox://styles/mapbox/basic-v9'
],
3 => [
'name' => 'Satellite',
'value' => 'mapbox://styles/mapbox/satellite-v9'
],
4 => [
'name' => 'Dark',
'value' => 'mapbox://styles/mapbox/dark-v9'
]
],
'transition-mapboxgl' => [
0 => [
'animate' => true,
'speed' => '2.2',
'curve' => '1.42'
]
],
'default-position' => [
'48.879162',
'2.335062'
],
'default-zoom' => 5,
'marker-default-zoom' => 9,
'position-fields' => [],
'geonames-field-mapping' => true,
'cityfields' => 'City, Ville',
'provincefields' => 'Province',
'countryfields' => 'Country, Pays'
];
$app['conf']->set(['geocoding-providers'], $providers);
}
// add video-editor section if not exist
if (!$app['conf']->has(['video-editor'])) {
$videoEditor = [
'ChapterVttFieldName' => 'VideoTextTrackChapters',
'seekBackwardStep' => 500,
'seekForwardStep' => 500,
'playbackRates' => [
1,
'1.5',
3
]
];
$app['conf']->set(['video-editor'], $videoEditor);
}
// add api_token_header if not exist
if (!$app['conf']->has(['main', 'api_token_header'])) {
$app['conf']->set(['main', 'api_token_header'], false);
}
// insert timeout if not exist
if (!$app['conf']->has(['main', 'binaries', 'ffmpeg_timeout'])) {
$app['conf']->set(['main', 'binaries', 'ffmpeg_timeout'], 3600);
}
if (!$app['conf']->has(['main', 'binaries', 'ffprobe_timeout'])) {
$app['conf']->set(['main', 'binaries', 'ffprobe_timeout'], 60);
}
if (!$app['conf']->has(['main', 'binaries', 'gs_timeout'])) {
$app['conf']->set(['main', 'binaries', 'gs_timeout'], 60);
}
if (!$app['conf']->has(['main', 'binaries', 'mp4box_timeout'])) {
$app['conf']->set(['main', 'binaries', 'mp4box_timeout'], 60);
}
if (!$app['conf']->has(['main', 'binaries', 'swftools_timeout'])) {
$app['conf']->set(['main', 'binaries', 'swftools_timeout'], 60);
}
if (!$app['conf']->has(['main', 'binaries', 'unoconv_timeout'])) {
$app['conf']->set(['main', 'binaries', 'unoconv_timeout'], 60);
}
if (!$app['conf']->has(['main', 'binaries', 'exiftool_timeout'])) {
$app['conf']->set(['main', 'binaries', 'exiftool_timeout'], 60);
}
// custom-link section, remove default store
$app['conf']->remove(['registry', 'custom-links', 0]);
$app['conf']->remove(['registry', 'custom-links', 1]);
$customLinks = [
'linkName' => 'Phraseanet store',
'linkLanguage' => 'all',
'linkUrl' => 'https://store.alchemy.fr',
'linkLocation' => 'help-menu',
'linkOrder' => 1,
'linkBold' => false,
'linkColor' => ''
];
$app['conf']->set(['registry', 'custom-links', 0], $customLinks);
return true;
}
}

View File

@@ -10,6 +10,7 @@ main:
maintenance: false maintenance: false
key: '' key: ''
api_require_ssl: true api_require_ssl: true
api_token_header: false
database: database:
host: 'sql-host' host: 'sql-host'
port: 3306 port: 3306

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"?> <?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"> <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
<file date="2020-05-26T10:28:28Z" source-language="en" target-language="de" datatype="plaintext" original="not.available"> <file date="2020-05-27T06:38:24Z" source-language="en" target-language="de" datatype="plaintext" original="not.available">
<header> <header>
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/> <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> <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"> <trans-unit id="96f0767cb7ea65a7f86c8c9432e80d16cf9d8680" resname="Please provide the same passwords." approved="yes">
<source>Please provide the same passwords.</source> <source>Please provide the same passwords.</source>
<target state="translated">Bitte geben Sie diesselbe Passwörter ein.</target> <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="36">Form/Login/PhraseaRenewPasswordForm.php</jms:reference-file>
<jms:reference-file line="44">Form/Login/PhraseaRecoverPasswordForm.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>
<trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore" approved="yes"> <trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore" approved="yes">
<source>The token provided is not valid anymore</source> <source>The token provided is not valid anymore</source>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?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"> <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
<file date="2020-05-26T10:28:56Z" source-language="en" target-language="en" datatype="plaintext" original="not.available"> <file date="2020-05-27T06:39:51Z" source-language="en" target-language="en" datatype="plaintext" original="not.available">
<header> <header>
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/> <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> <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"> <trans-unit id="96f0767cb7ea65a7f86c8c9432e80d16cf9d8680" resname="Please provide the same passwords." approved="yes">
<source>Please provide the same passwords.</source> <source>Please provide the same passwords.</source>
<target state="translated">Please provide the same passwords.</target> <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="36">Form/Login/PhraseaRenewPasswordForm.php</jms:reference-file>
<jms:reference-file line="44">Form/Login/PhraseaRecoverPasswordForm.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>
<trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore" approved="yes"> <trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore" approved="yes">
<source>The token provided is not valid anymore</source> <source>The token provided is not valid anymore</source>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?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"> <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
<file date="2020-05-26T10:29:25Z" source-language="en" target-language="fr" datatype="plaintext" original="not.available"> <file date="2020-05-27T06:41:25Z" source-language="en" target-language="fr" datatype="plaintext" original="not.available">
<header> <header>
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/> <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> <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"> <trans-unit id="96f0767cb7ea65a7f86c8c9432e80d16cf9d8680" resname="Please provide the same passwords." approved="yes">
<source>Please provide the same passwords.</source> <source>Please provide the same passwords.</source>
<target state="translated">Veuillez indiquer des mots de passe identiques.</target> <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="36">Form/Login/PhraseaRenewPasswordForm.php</jms:reference-file>
<jms:reference-file line="44">Form/Login/PhraseaRecoverPasswordForm.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>
<trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore" approved="yes"> <trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore" approved="yes">
<source>The token provided is not valid anymore</source> <source>The token provided is not valid anymore</source>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?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"> <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
<file date="2020-05-26T10:30:00Z" source-language="en" target-language="nl" datatype="plaintext" original="not.available"> <file date="2020-05-27T06:43:55Z" source-language="en" target-language="nl" datatype="plaintext" original="not.available">
<header> <header>
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/> <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> <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."> <trans-unit id="96f0767cb7ea65a7f86c8c9432e80d16cf9d8680" resname="Please provide the same passwords.">
<source>Please provide the same passwords.</source> <source>Please provide the same passwords.</source>
<target state="new">Please provide the same passwords.</target> <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="36">Form/Login/PhraseaRenewPasswordForm.php</jms:reference-file>
<jms:reference-file line="44">Form/Login/PhraseaRecoverPasswordForm.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>
<trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore"> <trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore">
<source>The token provided is not valid anymore</source> <source>The token provided is not valid anymore</source>

View File

@@ -5,3 +5,20 @@
@import '../../account/styles/skin'; @import '../../account/styles/skin';
@import '../../../../node_modules/font-awesome/scss/font-awesome.scss'; @import '../../../../node_modules/font-awesome/scss/font-awesome.scss';
@import '../../../../node_modules/jquery-ui/themes/base/autocomplete'; // not extension for inline import @import '../../../../node_modules/jquery-ui/themes/base/autocomplete'; // not extension for inline import
.authentication-sidebar {
.alert {
.alert-block-logo {
vertical-align: middle;
}
.fa-2x {
font-size: 2em;
height: 28px;
margin: 0;
background: none;
}
}
}

View File

@@ -46,8 +46,9 @@
<th class="sortable">{{ 'admin::workermanager:tab:workerinfo: record_id' | 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' | trans }}</th>
<th class="sortable">{{ 'admin::workermanager:tab:workerinfo: work_on' | trans }}</th> <th class="sortable">{{ 'admin::workermanager:tab:workerinfo: work_on' | trans }}</th>
<th class="sortable">{{ 'admin::workermanager:tab:workerinfo: created' | trans }}</th>
<th class="sortable">{{ 'admin::workermanager:tab:workerinfo: published' | trans }}</th> <th class="sortable">{{ 'admin::workermanager:tab:workerinfo: published' | trans }}</th>
<th class="sortable">{{ 'admin::workermanager:tab:workerinfo: created' | trans }}</th>
<th class="sortable">{{ 'admin::workermanager:tab:workerinfo: finished' | trans }}</th>
<th class="sortable">{{ 'admin::workermanager:tab:workerinfo: status' | trans }}</th> <th class="sortable">{{ 'admin::workermanager:tab:workerinfo: status' | trans }}</th>
</tr> </tr>
</thead> </thead>
@@ -60,8 +61,16 @@
<td>{{ workerRow.recordId }}</td> <td>{{ workerRow.recordId }}</td>
<td>{{ workerRow.getWorkName }}</td> <td>{{ workerRow.getWorkName }}</td>
<td>{{ workerRow.workOn }}</td> <td>{{ workerRow.workOn }}</td>
<td>{{ workerRow.created|date('Y-m-d H:i:s') }}</td>
<td>{{ workerRow.published|date('Y-m-d H:i:s') }}</td> <td>{{ workerRow.published|date('Y-m-d H:i:s') }}</td>
<td>{{ workerRow.created|date('Y-m-d H:i:s') }}</td>
<td>
{% if workerRow.finished %}
{{ workerRow.finished|date('Y-m-d H:i:s') }}
{% else %}
-
{% endif %}
</td>
<td>{{ workerRow.status }}</td> <td>{{ workerRow.status }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
@@ -72,7 +81,6 @@
<script type="text/javascript"> <script type="text/javascript">
$("#refresh-list").on('click', function () { $("#refresh-list").on('click', function () {
console.log("ato");
var running = 1; var running = 1;
var finished = 1; var finished = 1;
if (!$(".running-work").is(":checked")) if (!$(".running-work").is(":checked"))

View File

@@ -86,7 +86,7 @@
} }
}); });
} else { } else {
alert({{ "admin::workermanager:tab:searchengine: Warning Worker is in process to indexing one of the selected databox" |trans }}); alert('{{ "admin::workermanager:tab:searchengine: Warning Worker is in process to indexing one of the selected databox" |trans }}');
} }
} }
}); });

View File

@@ -140,12 +140,6 @@
</div> </div>
</form> </form>
<div>
<select name="upload_type" id="upload_type" class="input-large" style="width: 200px; float:right">
<option value="html" selected>{{ 'Use the HTML5 uploader' | trans }}</option>
<option value="flash">{{ 'Use the Flash uploader' | trans }}</option>
</select>
</div>
{% else %} {% else %}
{{ 'You can not upload files' | trans }} {{ 'You can not upload files' | trans }}
{% endif %} {% endif %}