
Как известно всем нашим клиентам, одно из кредо Smartling - «всегда предоставлять контекст». Следовательно, когда мы начали поддерживать Adobe InDesign, одна из задач, которая была поднята, заключалась в отображении контекста для файлов InDesign. Контекст перевода еще более важен для файлов InDesign, поскольку, в отличие от большинства веб-страниц, где часто есть место для увеличения или уменьшения текста, текст в файле InDesign должен умещаться в строго определенном пространстве, и переводчикам нужен способ проверить это их перевод подойдет. После некоторого покопания мы решили, что начнем с предоставления контекста, используя функцию экспорта Adobe InDesign Server в изображения. Мы рассмотрели несколько других возможностей реализации генерации контекста, но они оказались более трудоемкими при реализации / интеграции с нашей платформой. Сервер Indesign может легко конвертировать файлы в изображения - этого было достаточно для наших первоначальных целей.
Так как же нам обрабатывать этот экспорт на стороне InDesign Server? Он предоставляет возможность запускать сценарии на стороне сервера, написанные на AppleScript, VBScript и Javascript. Практически все, что вы можете делать с пользовательским интерфейсом, вы можете делать с помощью скриптов - это подтвердилось на нашем опыте. Мы реализовали сценарий на стороне сервера (javascript) для экспорта документа в виде набора изображений.
Внутренняя инфраструктура Smartling в основном основана на сервисах AWS, и подавляющее большинство серверов, которые мы используем, основаны на * nix. Поэтому нас ждал трудный выбор, когда нам нужно было выбрать платформу для запуска этого сервера - поскольку InDesign поддерживает только Windows и Mac OS :). У нас было несколько устройств Windows AWS, поэтому мы решили использовать Windows.
Дистрибутив Indesign Server поставляется с предустановленным балансировщиком нагрузки (далее LB). Он далек от совершенства - в документации указано, что он все еще находится в стадии бета-тестирования, - но мы решили использовать его вместо того, чтобы реализовывать что-то свое. Одна из проблем, связанных с этим выбором, заключается в том, что конечные точки LB не принимают составные файлы. Предполагается, что файлы уже находятся в каком-то доступном месте - либо в локальной FS, либо в общих сетевых папках. Это ограничение распространяется также на скрипты на стороне сервера - они также должны располагаться где-нибудь в локальной FS. Поскольку у нас уже были файлы InDesign, хранящиеся в amazon S3, для нас это не было большой проблемой - мы просто передаем путь S3 в качестве параметра для выполнения скрипта. С другой стороны, серверные скрипты Indesign находятся в локальной файловой системе и помещаются туда с помощью сценария развертывания.
Мы запускаем indesign server как с поддержкой CORBA, так и как веб-сервис. LB взаимодействует с сервером через CORBA, а мониторинг осуществляется через веб-сервис.
InDesignServer -iorfile <PATH_TO_IOR_FILE> -pluginpath Server\Corba -port <INDESIGN_PORT> -LogToApplicationEventLog
LB должен быть настроен с использованием пути к файлу ior:
[INDESIGN_SERVER_INSTALL_PATH]/JobQueue/configuration/idsQueue.properties should contain property iorFolder=<PATH_TO_IOR_FILE>
Процесс генерации контекста выглядит следующим образом:
1) Отправляем запрос на генерацию контекста в LB (‹INDESIGN_HOST› /com.adobe.clover.application/api/idsqueue/EnqueueJob). Запрос содержит url-адрес переменной «скрипт», в которой содержится исполнение файла скрипта:
app.doScript(File(‘</file/path/to/export.jsx>’), ScriptLanguage.JAVASCRIPT, [‘</s3/path/to/InDesign/file>’, ‘</s3/path/to/output/images>’, ‘/s3/bucket’, ‘ja’,…]
2) LB отправляет этот запрос на сервер Indesign. Которая загружает и выполняет сценарий экспорта на стороне сервера. Этот сценарий, в свою очередь, использует специальную утилиту для загрузки исходного файла InDesign с Amazon S3, а затем загружает изображения обратно туда, как только экспорт будет завершен.
3) Indesign Server сообщает LB и LB нашему приложению, что генерация завершена. Затем мы совершаем волшебство внутри нашего модуля парсеров, чтобы определить, какие строки принадлежат какой странице, и показать их конечному пользователю по запросу.
Следует упомянуть несколько интересных деталей о скрипте на стороне сервера:
- Все файловые операции привязаны к UID, который генерируется при запуске скрипта - это необходимо для предотвращения любых перекрытий, когда запросы генерируются одновременно сервером InDesign.
- Как вы понимаете, взаимодействие с Amazon S3 не является частью расширенной модели скриптов InDesign. Мы решили реализовать это с помощью утилиты, которая выполняет все эти операции и должна вызываться серверным скриптом InDesign. Однако вызов такой утилиты из скрипта на стороне сервера немного сложен.
var executableFile= File(baseTemporaryFolder + currentUid + “.bat”); executableFile.open(“w”); executableFile.write(‘utility.cmd — download “’ + newPath + ‘” & del “%~f0” & exit /b’); executableFile.close; executableFile.execute(); executableFile(newPath);
В нашем случае сценарий на стороне сервера должен знать целевой язык перевода. Это звучит странно, поэтому позвольте мне уточнить. Клиенты Smartling, переводящие документы InDesign, используют множество различных шрифтов, некоторые из которых мы не установили на нашем сервере - у нас не может быть их всех. У каждого шрифта есть свой набор символов, который он может отображать. Когда, например, перевод выполняется с английского на арабский - мы заменяем содержимое файла на арабский перевод, но мы должны что-то сделать со шрифтом, который не может отображать арабские символы. Вы не хотите, чтобы в вашем контексте отображалось что-то вроде:
Когда вы действительно ожидаете отображения арабских символов:
В нашем случае это достигается поддержанием языка по умолчанию - карты шрифтов:
var languageMap = new Object();
languageMap[‘ja’] = ‘FangSong’;
languageMap[‘ar’] = ‘Adobe Arabic’;
languageMap[‘ko’] = ‘Batang’;
if (typeof languageMap[targetLanguage] !== ‘undefined’)
{
doc.stories.everyItem().appliedFont = app.fonts.itemByName(languageMap[targetLanguage]);
}
Когда интеграция завершена - нам нужно настроить мониторинг. Чтобы отслеживать доступность InDesign Server, мы реализовали 2 проверки zabbix - одну для LB и одну для самого сервера. Кроме того, на стороне приложения настраиваются предупреждения - это позволит нам определить, если что-то пойдет не так между нашим приложением и экземпляром с сервером InDesign.
Вот суть проверки LB:
curl http://<INDESIGN_HOST>:9876/com.adobe.clover.application/api/GetVersion curl — header “Content-Type: text/xml;charset=UTF-8” — header “SOAPAction:urn:my:service-interaction:soap:RunScript” — data @runscript.xml http://[INDESIGN_HOST]:[INDESIGN_PORT]/Service.wsdl
Пример Runscript.xml:
<soapenv:Envelope xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn=”urn:my:service:types”>
<soapenv:Header/>
<soapenv:Body>
<ns1:RunScript xmlns:ns1=”http://ns.adobe.com/InDesign/soap/>
<runScriptParameters>
<scriptText>app.consoleout(‘Monitoring ping’);’Success’</scriptText>
<scriptLanguage>javascript</scriptLanguage>
</runScriptParameters>
</ns1:RunScript>
</soapenv:Body>
</soapenv:Envelope>