mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-15 05:53:13 +00:00
add translate for ginga
This commit is contained in:
@@ -468,7 +468,14 @@ class ToolsController extends Controller
|
|||||||
|
|
||||||
$this->dispatch(
|
$this->dispatch(
|
||||||
PhraseaEvents::RECORD_AUTO_SUBTITLE,
|
PhraseaEvents::RECORD_AUTO_SUBTITLE,
|
||||||
new RecordAutoSubtitleEvent($record, $permalinkUrl, $request->request->get("subtitle_language_source"), $request->request->get("meta_struct_id"))
|
new RecordAutoSubtitleEvent(
|
||||||
|
$record,
|
||||||
|
$permalinkUrl,
|
||||||
|
$request->request->get("subtitle_language_source"),
|
||||||
|
$request->request->get("meta_struct_id_source"),
|
||||||
|
$request->request->get("subtitle_language_destination"),
|
||||||
|
$request->request->get("meta_struct_id_destination")
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->app->json(["status" => "dispatch"]);
|
return $this->app->json(["status" => "dispatch"]);
|
||||||
|
@@ -7,16 +7,27 @@ use Alchemy\Phrasea\Model\RecordInterface;
|
|||||||
class RecordAutoSubtitleEvent extends RecordEvent
|
class RecordAutoSubtitleEvent extends RecordEvent
|
||||||
{
|
{
|
||||||
private $languageSource;
|
private $languageSource;
|
||||||
private $metaStructId;
|
private $metaStructureIdSource;
|
||||||
|
private $languageDestination;
|
||||||
|
private $metaStructureIdDestination;
|
||||||
private $permalinkUrl;
|
private $permalinkUrl;
|
||||||
|
|
||||||
public function __construct(RecordInterface $record, $permalinkUrl, $languageSource, $metaStructId)
|
public function __construct(
|
||||||
|
RecordInterface $record,
|
||||||
|
$permalinkUrl,
|
||||||
|
$languageSource,
|
||||||
|
$metaStructureIdSource,
|
||||||
|
$languageDestination,
|
||||||
|
$metaStructureIdDestination
|
||||||
|
)
|
||||||
{
|
{
|
||||||
parent::__construct($record);
|
parent::__construct($record);
|
||||||
|
|
||||||
$this->languageSource = $languageSource;
|
$this->languageSource = $languageSource;
|
||||||
$this->metaStructId = $metaStructId;
|
$this->metaStructureIdSource = $metaStructureIdSource;
|
||||||
$this->permalinkUrl = $permalinkUrl;
|
$this->languageDestination = $languageDestination;
|
||||||
|
$this->metaStructureIdDestination = $metaStructureIdDestination;
|
||||||
|
$this->permalinkUrl = $permalinkUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLanguageSource()
|
public function getLanguageSource()
|
||||||
@@ -24,9 +35,19 @@ class RecordAutoSubtitleEvent extends RecordEvent
|
|||||||
return $this->languageSource;
|
return $this->languageSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getMetaStructId()
|
public function getMetaStructureIdSource()
|
||||||
{
|
{
|
||||||
return $this->metaStructId;
|
return $this->metaStructureIdSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLanguageDestination()
|
||||||
|
{
|
||||||
|
return $this->languageDestination;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMetaStructureIdDestination()
|
||||||
|
{
|
||||||
|
return $this->metaStructureIdDestination;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPermalinkUrl()
|
public function getPermalinkUrl()
|
||||||
|
@@ -132,7 +132,9 @@ class AlchemyWorkerServiceProvider implements PluginProviderInterface
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
$app['alchemy_worker.type_based_worker_resolver']->addFactory(MessagePublisher::SUBTITLE_TYPE, new CallableWorkerFactory(function () use ($app) {
|
$app['alchemy_worker.type_based_worker_resolver']->addFactory(MessagePublisher::SUBTITLE_TYPE, new CallableWorkerFactory(function () use ($app) {
|
||||||
return new SubtitleWorker($app['repo.worker-job'], $app['conf'], new LazyLocator($app, 'phraseanet.appbox'), $app['alchemy_worker.logger']);
|
return (new SubtitleWorker($app['repo.worker-job'], $app['conf'], new LazyLocator($app, 'phraseanet.appbox'), $app['alchemy_worker.logger']))
|
||||||
|
->setFileSystemLocator(new LazyLocator($app, 'filesystem'))
|
||||||
|
->setTemporaryFileSystemLocator(new LazyLocator($app, 'temporary-filesystem'));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
$app['alchemy_worker.type_based_worker_resolver']->addFactory(MessagePublisher::MAIN_QUEUE_TYPE, new CallableWorkerFactory(function () use ($app) {
|
$app['alchemy_worker.type_based_worker_resolver']->addFactory(MessagePublisher::MAIN_QUEUE_TYPE, new CallableWorkerFactory(function () use ($app) {
|
||||||
|
@@ -32,11 +32,13 @@ class SubtitleSubscriber implements EventSubscriberInterface
|
|||||||
$em = $this->repoWorkerJob->getEntityManager();
|
$em = $this->repoWorkerJob->getEntityManager();
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
"databoxId" => $event->getRecord()->getDataboxId(),
|
"databoxId" => $event->getRecord()->getDataboxId(),
|
||||||
"recordId" => $event->getRecord()->getRecordId(),
|
"recordId" => $event->getRecord()->getRecordId(),
|
||||||
"permalinkUrl" => $event->getPermalinkUrl(),
|
"permalinkUrl" => $event->getPermalinkUrl(),
|
||||||
"langageSource" => $event->getLanguageSource(),
|
"languageSource" => $event->getLanguageSource(),
|
||||||
"metaStructureId" => $event->getMetaStructId()
|
"metaStructureIdSource" => $event->getMetaStructureIdSource(),
|
||||||
|
"languageDestination" => $event->getLanguageDestination(),
|
||||||
|
"metaStructureIdDestination" => $event->getMetaStructureIdDestination()
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->repoWorkerJob->reconnect();
|
$this->repoWorkerJob->reconnect();
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace Alchemy\Phrasea\WorkerManager\Worker;
|
namespace Alchemy\Phrasea\WorkerManager\Worker;
|
||||||
|
|
||||||
|
use Alchemy\Phrasea\Application\Helper\FilesystemAware;
|
||||||
use Alchemy\Phrasea\Core\Configuration\PropertyAccess;
|
use Alchemy\Phrasea\Core\Configuration\PropertyAccess;
|
||||||
use Alchemy\Phrasea\Model\Entities\WorkerJob;
|
use Alchemy\Phrasea\Model\Entities\WorkerJob;
|
||||||
use Alchemy\Phrasea\Model\Repositories\WorkerJobRepository;
|
use Alchemy\Phrasea\Model\Repositories\WorkerJobRepository;
|
||||||
@@ -10,6 +11,8 @@ use Psr\Log\LoggerInterface;
|
|||||||
|
|
||||||
class SubtitleWorker implements WorkerInterface
|
class SubtitleWorker implements WorkerInterface
|
||||||
{
|
{
|
||||||
|
use FilesystemAware;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var callable
|
* @var callable
|
||||||
*/
|
*/
|
||||||
@@ -50,31 +53,40 @@ class SubtitleWorker implements WorkerInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
$workerJob->setStatus(WorkerJob::RUNNING)
|
$workerJob->setStatus(WorkerJob::RUNNING)
|
||||||
->setStarted(new \DateTime('now'));
|
->setStarted(new \DateTime('now'));
|
||||||
|
|
||||||
$em = $this->repoWorkerJob->getEntityManager();
|
$em = $this->repoWorkerJob->getEntityManager();
|
||||||
$this->repoWorkerJob->reconnect();
|
$this->repoWorkerJob->reconnect();
|
||||||
$em->persist($workerJob);
|
$em->persist($workerJob);
|
||||||
$em->flush();
|
$em->flush();
|
||||||
|
|
||||||
|
switch ($gingaTranscriptFormat) {
|
||||||
|
case 'text/srt,':
|
||||||
|
$extension = 'srt';
|
||||||
|
break;
|
||||||
|
case 'text/plain':
|
||||||
|
$extension = 'txt';
|
||||||
|
break;
|
||||||
|
case 'application/json':
|
||||||
|
$extension = 'json';
|
||||||
|
break;
|
||||||
|
case 'text/vtt':
|
||||||
|
default:
|
||||||
|
$extension = 'vtt';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$languageSource = $this->getLanguageFormat($payload['languageSource']);
|
||||||
|
$languageDestination = $this->getLanguageFormat($payload['languageDestination']);
|
||||||
|
|
||||||
$record = $this->getApplicationBox()->get_databox($payload['databoxId'])->get_record($payload['recordId']);
|
$record = $this->getApplicationBox()->get_databox($payload['databoxId'])->get_record($payload['recordId']);
|
||||||
|
$languageSourceFieldName = $record->getDatabox()->get_meta_structure()->get_element($payload['meta_struct_id_source'])->get_name();
|
||||||
|
|
||||||
if ($payload['permalinkUrl'] != '' && $payload['metaStructureId']) {
|
$subtitleSourceTemporaryFile = $this->getTemporaryFilesystem()->createTemporaryFile("subtitle", null, $extension);
|
||||||
switch ($payload['langageSource']) {
|
$gingerClient = new Client();
|
||||||
case 'En':
|
|
||||||
$language = 'en-GB';
|
|
||||||
break;
|
|
||||||
case 'De':
|
|
||||||
$language = 'de-DE';
|
|
||||||
break;
|
|
||||||
case 'Fr':
|
|
||||||
default:
|
|
||||||
$language = 'fr-FR';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$gingerClient = new Client();
|
|
||||||
|
|
||||||
|
// if the languageSourceFieldName do not yet exist, first generate subtitle for it
|
||||||
|
if ($payload['permalinkUrl'] != '' && !$record->get_caption()->has_field($languageSourceFieldName)) {
|
||||||
try {
|
try {
|
||||||
$response = $gingerClient->post($gingaBaseurl.'/media/', [
|
$response = $gingerClient->post($gingaBaseurl.'/media/', [
|
||||||
'headers' => [
|
'headers' => [
|
||||||
@@ -82,7 +94,7 @@ class SubtitleWorker implements WorkerInterface
|
|||||||
],
|
],
|
||||||
'json' => [
|
'json' => [
|
||||||
'url' => $payload['permalinkUrl'],
|
'url' => $payload['permalinkUrl'],
|
||||||
'language' => $language
|
'language' => $languageSource
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
@@ -144,7 +156,7 @@ class SubtitleWorker implements WorkerInterface
|
|||||||
'ACCEPT' => $gingaTranscriptFormat
|
'ACCEPT' => $gingaTranscriptFormat
|
||||||
],
|
],
|
||||||
'query' => [
|
'query' => [
|
||||||
'language' => $language
|
'language' => $languageSource
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
@@ -165,8 +177,11 @@ class SubtitleWorker implements WorkerInterface
|
|||||||
|
|
||||||
$transcriptContent = preg_replace('/WEBVTT/', 'WEBVTT - with cue identifier', $transcriptContent, 1);
|
$transcriptContent = preg_replace('/WEBVTT/', 'WEBVTT - with cue identifier', $transcriptContent, 1);
|
||||||
|
|
||||||
|
// save subtitle on temporary file to use to translate if needed
|
||||||
|
file_put_contents($subtitleSourceTemporaryFile, $transcriptContent);
|
||||||
|
|
||||||
$metadatas[0] = [
|
$metadatas[0] = [
|
||||||
'meta_struct_id' => (int)$payload['metaStructureId'],
|
'meta_struct_id' => (int)$payload['metaStructureIdSource'],
|
||||||
'meta_id' => '',
|
'meta_id' => '',
|
||||||
'value' => $transcriptContent
|
'value' => $transcriptContent
|
||||||
];
|
];
|
||||||
@@ -180,7 +195,77 @@ class SubtitleWorker implements WorkerInterface
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->logger->info("Auto subtitle SUCCESS");
|
$this->logger->info("Generate subtitle on language source SUCCESS");
|
||||||
|
} elseif ($record->get_caption()->has_field($languageSourceFieldName)) {
|
||||||
|
// get the source subtitle and save it to a temporary file
|
||||||
|
$fieldValues = $record->get_caption()->get_field($languageSourceFieldName)->get_values();
|
||||||
|
$fieldValue = array_pop($fieldValues);
|
||||||
|
|
||||||
|
file_put_contents($subtitleSourceTemporaryFile, $fieldValue->getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($payload['metaStructureIdSource'] !== $payload['metaStructureIdDestination']) {
|
||||||
|
try {
|
||||||
|
$response = $gingerClient->post($gingaBaseurl.'/translate/', [
|
||||||
|
'headers' => [
|
||||||
|
'Authorization' => 'token '.$gingaToken,
|
||||||
|
'ACCEPT' => $gingaTranscriptFormat
|
||||||
|
],
|
||||||
|
'multipart' => [
|
||||||
|
[
|
||||||
|
'name' => 'transcript',
|
||||||
|
'contents' => fopen($subtitleSourceTemporaryFile, 'r')
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'transcript_format',
|
||||||
|
'contents' => $gingaTranscriptFormat,
|
||||||
|
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'language_in',
|
||||||
|
'contents' => $languageSource,
|
||||||
|
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'language_out',
|
||||||
|
'contents' => $languageDestination,
|
||||||
|
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
$this->logger->error($e->getMessage());
|
||||||
|
$this->jobFinished($workerJob);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($response->getStatusCode() !== 200) {
|
||||||
|
$this->logger->error("response status /translate/ : ". $response->getStatusCode());
|
||||||
|
$this->jobFinished($workerJob);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$transcriptContent = $response->getBody()->getContents();
|
||||||
|
$transcriptContent = preg_replace('/WEBVTT/', 'WEBVTT - with cue identifier', $transcriptContent, 1);
|
||||||
|
|
||||||
|
$metadatas[0] = [
|
||||||
|
'meta_struct_id' => (int)$payload['metaStructureIdDestination'],
|
||||||
|
'meta_id' => '',
|
||||||
|
'value' => $transcriptContent
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$record->set_metadatas($metadatas);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->logger->error($e->getMessage());
|
||||||
|
$this->jobFinished($workerJob);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->logger->info("Translate subtitle on language destination SUCCESS");
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->jobFinished($workerJob);
|
$this->jobFinished($workerJob);
|
||||||
@@ -209,4 +294,17 @@ class SubtitleWorker implements WorkerInterface
|
|||||||
$em->persist($workerJob);
|
$em->persist($workerJob);
|
||||||
$em->flush();
|
$em->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getLanguageFormat($language)
|
||||||
|
{
|
||||||
|
switch ($language) {
|
||||||
|
case 'En':
|
||||||
|
return 'en-GB';
|
||||||
|
case 'De':
|
||||||
|
return 'de-DE';
|
||||||
|
case 'Fr':
|
||||||
|
default:
|
||||||
|
return 'fr-FR';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -366,8 +366,10 @@
|
|||||||
data: {
|
data: {
|
||||||
databox_id: {{ record.getDataboxId }},
|
databox_id: {{ record.getDataboxId }},
|
||||||
record_id: {{ record.getRecordId }},
|
record_id: {{ record.getRecordId }},
|
||||||
meta_struct_id: $('#subtitle_language_source').val(),
|
subtitle_language_source: $('#subtitle_language_source option:selected').text(),
|
||||||
subtitle_language_source: $('#subtitle_language_source option:selected').text()
|
meta_struct_id_source: $('#subtitle_language_source').val(),
|
||||||
|
subtitle_language_destination: $('#subtitle_language_destination option:selected').text(),
|
||||||
|
meta_struct_id_destination: $('#subtitle_language_destination').val()
|
||||||
},
|
},
|
||||||
success: function success(data) {
|
success: function success(data) {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
|
Reference in New Issue
Block a user