Наша команда Mobile Doc&Loc «Лаборатории Касперского» занимается подготовкой документации и локализации B2C-продуктов компании для мобильных устройств. Основная сложность (и одновременно фишка) нашей работы заключается в том, что необходимо регулярно подготавливать переводы на 34 языка в крайне сжатые сроки.

Меня зовут Юлиана Соломатина, я — Doc&Loc-инженер, и в этой статье я расскажу про инструменты-автоматизации, которые помогают нам справляться с наплывом задач и укладываться в дедлайны, не жертвуя при этом качеством. Кстати, многие из этих инструментов мы разработали сами.

Если же вам интересно узнать о самих процессах, то очень рекомендую эту статью моего коллеги Никиты Авилова. Он подробно рассказал, почему мы переводим все тексты именно с английского, как мы внедрили машинный перевод, каким образом мы взаимодействуем с подрядчиками, и поэтапно расписал алгоритмы локализации GUI-текстов, онлайн-справок и юридических документов. Я же сосредоточусь именно на инструментах, которые мы используем в нашей работе.

Синкер

Это сервис двусторонней синхронизации локализуемых ресурсов между закрытыми VCS, используемыми в компании (tfs, git/monorepo), и доступным «снаружи» сервисом, в котором могут работать внештатные лингвисты. При синхронизации производится двусторонняя конвертация форматов из множества используемых в один универсальный — XML, выкладываемый в облачный CAT для перевода. В качестве CAT используется сервис Smartcat. Синкер помогает локализаторам в пару кликов выгружать ресурсные файлы, справки и соглашения из рабочих директорий в Smartcat и обратно.

Визуально Синкер представляет собой веб-страницу со списком файлов конфигураций. Для каждого продукта и типа локализуемых ресурсов создается свой конфиг-файл.

Для запуска синхронизации необходимо заполнить следующие поля:

  • BranchSource, BranchTarget — ветки для загрузки и выгрузки файлов соответственно;

  • IntSource, IntTarget — директория, в которой хранится сорсовый (англоязычный) файл, и директория, в которую будет загружен переведенный файл;

  • ExtSource, ExtTarget — названия файлов в Смарткате;

  • ToExt1, ToInt1 — названия парсеров для конвертации из исходного формата в xml и обратно;

  • ExtPush, ExtPull — команды для загрузки и выгрузки с указанием ID проекта в Смарткате.

 В нижней части конфига, в специальной переменной Languages, прописаны языковые коды для локализаций. Данная переменная участвует в заполнении полей IntTarget, ExtSource, ExtTarget. Благодаря этому переведенные файлы загружаются в соответствующие языковые папки.

При работе над локализационной задачей инженеру требуется вносить лишь минимальные изменения в структуру конфига, а именно:

  • Указать актуальную рабочую ветку.

  • Комментировать ненужные поля и блоки конфига.

Остальные поля остаются неизменными и редактируются лишь тогда, когда в проекте происходят структурно важные изменения (например, появляются новые файлы или меняется ID проекта в Смарткате).

После настройки конфига локализатору остается запустить выгрузку с помощью клика на кнопку Run и дождаться завершения выгрузки (т. е. смены состояния на Completed).

Парсеры

На разных этапах локализации мы используем разные программы, которые читают разные форматы файлов. Поэтому, чтобы локализуемые файлы быстро и корректно конвертировались из форматов, используемых в разработке (html, txt и др.), в формат, который может прочитать Смарткат (XML), и обратно, мы используем парсеры. У нас они основаны на правилах и регулярных выражениях. Парсеры имеют единый шаблон с фиксированными полями:

 Rules — список правил.

У каждого правила обязательны:

  • тип сегмента: type (тип обычного сегмента — string);

  • регулярные выражения, определяющие начало и конец сегмента: (begins, ends).

map — словарь замен в указанном порядке. 

map_data — опциональный словарь замен для частей файла, не относящихся к переводимому тексту. Может отсутствовать, тогда замены во всем файле будут делаться по словарю map.

map_pre_parse — опциональный словарь замен для всего содержимого исходного файла (после выгрузки из VCS, до парсинга). Может отсутствовать.

map_post_parse — опциональный словарь замен для всего содержимого xml-файла (после парсинга, до загрузки в САТ). Может отсутствовать.

map_use_regex — если параметр присутствует, для замен map и map_data включается режим регулярных выражений (regex.sub).

map_empty — опциональная замена пустого сегмента сорса на указанную последовательность символов. Нужна для обхода неспособности СК работать с пустыми сегментами сорса.

source_encoding — кодировка по умолчанию, может быть переопределена при запуске.

Применение парсеров позволяет нам экономить время и сводить к минимуму риск ошибки в процессе перехода от одного формата файлов к другому, а благодаря использованию единого шаблона для написания правил нам удобно и легко поддерживать наши парсеры — вносить изменения, исправлять ошибки и добавлять новые правила.

Автотесты

При обработке такого большого пула локализаций невозможно вручную отследить все возможные ошибки. Конечно, мы могли бы запускать QA-инструменты, например XBench или AssurIT, по каждому языку каждой задачи, но это достаточно монотонная и затратная по времени задача. Так что здесь нас очень выручают автотесты — система автоматической проверки локализационных ресурсов на предмет технических и лингвистических ошибок. Автотесты работают круглосуточно, они обновляют локальные копии проектных репозиториев и проверяют проектные файлы, как в фоновом режиме, так и по запросам пользователей. Большинство тестов производит статический анализ локализационных файлов (т. е. не моделирует какой-либо продукт или тестовую среду) на основе регулярных выражений, белых списков, заранее заданных правил и эвристики.

Большая часть тестов проверяет любой переданный им файл, но есть также тесты, содержащие специфические проверки, которые применяются только для конкретных типов ресурсов (онлайн-справка, соглашения и т. д.). По завершении проверок система генерирует отчет, доступный пользователям на портале сервиса. Важно отметить, автотесты не вносят никаких правок в файлы — они лишь указывают на ошибки, после чего инженеру по локализации необходимо самому или с помощью лингвистов внести правки в нужные строки файла. Команда инженеров, занимающихся поддержкой автотестов, периодически создает новые тесты, вносит доработки в существующие тесты по запросам команд, так как время от времени к тестам добавляются новые проекты, меняются форматы глоссариев и других внешних источников данных, что может приводить к ложным срабатываниям или, наоборот, пропускам ошибок.

Какие ошибки могут отлавливать автотесты? Например, пропуски тегов в html-файлах, ошибки пунктуации, несоответствие глоссарию, опечатки в названиях продуктов, правильность написания копирайтов, некорректное форматирование текста и другие.

В мобильной команде автотесты в основном применяются для проверок юридических соглашений, что позволяет быстро находить и исправлять ошибки. Это очень существенно, так как финальные соглашения приходят в локализацию накануне релиза, и экономия времени — особенно важный вопрос.

HashID 

Одна из самых трудоемких задач в локализации — сделать так, чтобы названия интерфейсных элементов в документации в точности соответствовали интерфейсу программы. Это важная задача, ведь если названия GUI-элементов в справке отличаются от названий в приложении, это значительно ухудшает пользовательский опыт. Сверять все названия вручную нерационально ввиду сжатых сроков, многочисленных языков локализаций и больших объемов документации. Поэтому, вместо того чтобы сверять GUI-элементы после перевода, мы придумали подставлять их непосредственно из файлов GUI и для этого внедрили HashID — уникальные идентификаторы интерфейсных элементов.

Идентификаторы HashID формируются из двух частей: имени файла в проекте Смартката и внутреннего идентификатора строки в этом файле. Соединяем их через разделитель «|» и получаем, к примеру, strings.xml#master.xml| str_license_title. Но в таком виде использовать идентификаторы неудобно: они получаются громоздкими, потому возрастает вероятность ошибки при копипасте. Тогда мы можем посчитать MD5-hash от этой строки. Получаем: ca70549529adf14ec2b2733f12f743c9. Далее кодируем его в base58 (в отличие от base64, эта кодировка не содержит неоднозначных символов типа 0 и О — это помогает при ручном вводе), получаем: 7gwLirr8FcSEfTkLXg6j7hMp45biixPaTg5zdP8Rb7jn. Такой идентификатор все еще очень длинный, и, по сути, эта длина избыточна. Если сократить его до последних 6 символов, то мы получим 586 =38 млрд уникальных комбинаций. На проекте объемом 20 тысяч строк вероятность коллизии менее 0,5%. Итак, HashID формируется из последних 6 символов MD5-хеша, закодированного перед этим в base58.

Для удобства все идентификаторы заключаются в парные квадратные скобки [[]]. Такой «тег» редко где используется и выглядит более-менее компактно. Обозначить нужно и начало, и конец названия, например:

In the Settings section, enable Kill Switch. ->

In the [[MNGyRqjR]]Settings[[]] section, enable [[RirfPA5g]]Kill Switch[[]].

Проставлять хеши в тексте документации — задача технического писателя. Для этого необходимо сначала сгенерировать XLSX-таблицу с GUI-элементами и их хешами, экспортированными из нужного проекта в Смарткате. Таблица выглядит вот так:

Далее нужно к каждому GUI-элементу в топиках справки в AuthorIT добавить его HashID, взятый из второго столбца в таблице. Тексты GUI-элементов находятся в третьем столбце, первый столбец (полный идентификатор) помогает найти правильную строку, когда есть несколько совпадающих или похожих вариантов.

После подстановки HashID писатель экспортирует справку в html-формат и передает локализаторам. Экспортированная справка будет содержать хеши, заключенные в двойные квадратные скобки (как в примере выше). Отдавать ее в таком виде на перевод нельзя: идентификаторы в квадратных скобках для переводчика будут выглядеть как обычные слова, это создаст дополнительные fuzzy matches и в результате лишнюю работу. Чтобы этого избежать, можно сконвертировать формат тегов из квадратных скобок в html-теги <span>...</span>:

In the <span class="hash" id=”MNGyRqjR”>Settings</span> section, enable <span class="hash" id=”RirfPA5g”>Kill Switch</span>.

Теги <span> не видны в браузере, но при этом Смарткат их распознает и экранирует так, чтобы переводчик не смог их изменить. Вот как выглядит основной экран утилиты, в которой мы работаем с идентификаторами:

Получив переводы документации, локализатор должен подставить вместо хешей переводы из GUI. Для этого он выбирает все нужные ему языки, подключает соответствующий проект из Смартката и выбирает опцию Replace tags in html в утилите. Процесс замены хешей занимает несколько минут, после чего справка отправляется на публикацию.

Таким образом, использование HashID значительно упрощает и ускоряет процесс работы над справкой, а также сводит к нулю вероятность ошибок или несоответствий в упоминаниях GUI-элементов. 

ScreenshotLab

Один из важных этапов локализации — проверка переведенных текстов на скриншотах с целью выявить и исправить возможные косметические и лингвистические баги. Для автоматизации данного процесса мы создали специальную утилиту ScreenshotLab. Она выполняет две основные функции: создание пакета для отправки лингвисту на тестирование (сравнение скриншотов Source <-> Target) и заведение багов на скриншоты.

Получив скриншоты на всех нужных языках с помощью «Автоскриншотилки» (еще одной программы, которая автоматически делает скриншоты приложений по заданным параметрам), локализатор создает специальные пакеты для тестирования. Пакет представляет собой файл формата *.klscreen, в котором в одном окне попарно сопоставляются английский и локализованный скриншоты.

Поскольку языков и папок со скриншотами в рамках отдельной задачи может оказаться очень много, создавать такие пакеты вручную было бы затруднительно. Для облегчения этого шага используется еще одна утилита, которая устанавливается в контекстное меню Проводника и позволяет создать все пакеты для всех папок с языками одним кликом: для этого лишь необходимо, чтобы названия для одного и того же скриншота и структура папок были одинаковые для всех языков (по умолчанию это так и есть).

Готовые пакеты отправляются лингвистам на проверку. Проверяющий должен пометить каждый скриншот как корректный или бажный. Список обработанных скриншотов выглядит следующим образом:

Если на скриншоте обнаружился баг, то проверяющему лингвисту необходимо описать проблему и предложить ее решение. Далее локализатор, принимая во внимание особенности продукта, структуру формата строк (включая переменные, плейсхолдеры, переиспользование строк в других проектах и т. д.) и следя за консистентностью, принимает решение о внесении предложенной правки. А чтобы локализатору было проще обрабатывать результат, в окне для написания комментария заданы специальные поля:

  • Actual result/Current result: строка со скриншота, в которой обнаружился баг;

  • Expected result/Suggested translation: корректный перевод для этой же строки, предлагаемый вендором;

  • Source text: та же строка на английском.

Итак, ScreenshotLab позволяет значительно оптимизировать процесс лингвистического тестирования и обеспечивает удобство заведения и обработки багов.

Terminarium

Терминариум — это решение, которое помогает нам поддерживать единообразие терминологии для разных проектов компании и для разных платформ. Сервис состоит из следующих компонентов:

  • База данных здесь хранятся все концепты и термины. Каждый концепт и каждый термин имеют уникальный идентификационный номер (ID), поэтому перепутать их невозможно.

  • Веб-интерфейс используется для добавления концептов и терминов в базу данных Терминариума. Также можно экспортировать в нем наборы терминов во внешний xlsx-файл и при необходимости импортировать его обратно.

    • API — сервисы, дублирующие функции веб-портала, которыми может пользоваться любой сотрудник доклока.

    • Плагины их можно использовать для интеграции офлайн с CAT-инструментами, например Passolo или Trados.

    • Интеграции — логические коннекторы, позволяющие, наоборот, использовать внешние API. На настоящий момент есть интеграция со Смарткатом.

Для понимания устройства Терминариума и особенностей работы с ним важно ввести следующие понятия:

  • Концепт — понятие конкретной предметной области, которое фигурирует в письменных материалах компании, таких как графический интерфейс, руководства пользователя и администратора или примечания к выпуску. К ним относятся, например, названия приложений и сервисов, фичи приложений, общие IT-термины и т. п. Такие понятия-концепты заносятся в систему в виде четких определений на английском языке.

  • Термин — это слово или фраза, используемые для выражения концепта. Во многих случаях концепт можно выразить с помощью только одного термина. Например, для концепта «Имя веб-сайта "Лаборатории Касперского" для управления устройствами и лицензиями» может быть только один термин — «My Kaspersky». В некоторых концептах может быть больше одного термина. Например, термин «Полное имя приложения» может различаться в разных проектах.

  • Функциональная область концепта указывает ту область, в которой можно встретить этот концепт и связанные с ним термины. Например, функциональной областью может быть «лицензирование», «графический интерфейс» или «обновление».

  • Проект@Платформа@Версия (сокращенно ППВ) — иерархия, используемая для организации структуры проекта. Например, есть проект Kaspersky Password Manager. Внутри этого проекта существуют платформы macOS, Windows, Android и т. д. Внутри каждой из этих платформ есть своя версионность, где термины также могут различаться. Такая структура позволяет вести гибкую версионность проектных терминов по аналогии с «ветками» в системе контроля версий.

    • Версия main содержит самую актуальную терминологию для проекта и платформы.

    • Платформа Shared — перечень терминов, актуальных для всех платформ данного продукта. Так как внутри одного проекта большую часть терминологии составляют термины, которые актуальны для всех платформ (это могут быть названия функциональных возможностей или вариантов лицензирования продукта), то если добавить такие термины в глоссарий каждой платформы, есть вероятность, что со временем они могут рассинхронизироваться. Shared помогает избежать этого и сделать задачу поддержки терминологии удобнее.

  • Forbidden terms — отдельный раздел со списком терминологии, которая запрещена к использованию в продуктах компании в соответствии с общепринятыми принципами вежливости и морали.

  • Статус — текущее состояние термина. Например, статус Approved означает, что термин утвержден и может быть использован в продукте, а статус Obsolete присваивается устаревшим терминам.

Терминариум содержит не только определение термина на английском, но и утвержденные переводы на все языки локализации.

Благодаря интеграции со Смарткатом фрилансерам, работающим над переводами по нашим задачам, видны все термины, которые присутствуют в строке и которые необходимо перевести определенным образом. На этапе лингвистического тестирования также происходит проверка на соответствие глоссарию: для этого кроме отправки самих скриншотов локализатор также назначает на переводчика проект Смарткат, в котором терминология подключена как термбаза.

Что дальше

Мы продолжаем активно улучшать функционал имеющихся инструментов и планируем внедрять новые. Среди ближайших планов — разработка пайплайна для автоматизации обработки пользовательского фидбэка на документацию. Наши юзеры с разных стран регулярно дают обратную связь на онлайн-справку по нашим продуктам, и очень важно своевременно выявлять проблемные места в справке и направлять информацию продуктовой команде. Мы уже активно работаем над MVP, применяя современные методы анализа данных, в частности NLP-технологии. 

А еще в других командах внутри Doc&Loc есть свои разработки, которые мы периодически заимствуем и настраиваем под свои проекты. Так, например, мы планируем внедрять утилиту для сбора статистики прогонов скриншотилки, фильтрации скриншотов и распознавания текста на них, которая уже активно применяется на проектах Mac. Это поможет нам еще лучше оптимизировать процесс лингвистического тестирования.

Кстати, освоить новые инструменты и интегрировать их в нашу работу можете и вы: приходите к нам в отдел документирования и локализации (Doc&Loc) «Лаборатории Касперского». Сможете вместе с нами работать над локализацией на рекордные 34 языка и применять все инструменты, которые я описала, а при желании — создать свои :)

Комментарии (0)