Статьи

Социальный перевод приложения на платформе NetBeans


Недавно моя компания (
Streamsim Technologies ) решила перевести наше программное обеспечение на китайский и португальский языки; У нас есть клиенты в Китае и Бразилии, поэтому мы подумали, что перевод нашего проекта поможет нам еще больше выйти на эти рынки. Мы подумали о социальном переводе, что-то вроде: пользователь заходит на наш веб-сайт, находит текст, который он хочет перевести, и переводит его, поэтому при следующем обновлении он увидит, что его изменения применяются. Мы знали, что есть сайты, позволяющие это сделать, например,
www.getlocalization.com , и поэтому решили провести некоторые расследования.

Мы обнаружили, что еще несколько компаний предоставляют веб-приложения для социального перевода, вот их список:

Наши требования:

  • Поддержка дальневосточных языков (упрощенный китайский и японский).

  • Поддержка свойств Java (нас не заботила поддержка UTF-8).

  • Вызываемый API из Java (REST в порядке) или способ извлечь переводы.

  • Поддержка нескольких пользователей.

  • Возможность утверждать или оценивать переводы.

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

Больше всего нам понравились transifex, crowin и последнее время pootle, но мы рассмотрели также getlocalization, поскольку он предоставляет Java API и wordbee, которые имеют много функций, но они в большей степени ориентированы на индивидуальный переводчик.

Transifex был моим личным выбором, потому что он был прост в использовании, предлагал REST API, позволял редакторам проверять перевод и поддерживал свойства Java. Мы также много раз обращались за поддержкой, и нам всегда давали быстрый ответ. Transifex написан на Python и был с открытым исходным кодом почти год назад. Он предлагает бесплатный хостинг для проектов с открытым исходным кодом и несколько цен в зависимости от размера проекта, который вы хотите перевести. Есть еще одно приложение на платформе NetBeans под названием Gephi, которое использует Transifex для своих переводов; Вы можете увидеть, как они работают вместе здесь:

http://wiki.gephi.org/index.php/Localization . Они также написали несколько скриптов на Python для автоматизации работы здесь: http://github.com/gephi/gephi/tree/master/translations .

Мой проект Leader очень понравился толпе, он имеет те же функции, что и Transifex, выглядит немного лучше и кажется более сфокусированным на качестве. Это не с открытым исходным кодом.

Поэтому сначала я создал 30-дневную пробную учетную запись на Transifex и написал несколько инструментов для загрузки наших файлов свойств Java и загрузки переведенной версии. Это было легко, так как мне просто нужно запустить программу Linux под названием curl. Curl выполняет HTTP-запрос и выводит ответ в файл или на стандартный вывод; ответ в формате JSON, и я использовал Google Gson ( code. google .com / p / googlegson /) разобрать это. API довольно прост, поскольку вам нужно просто создать класс, поля которого соответствуют ключам в данных JSON, и объект автоматически заполняется. Все шло хорошо, пока я не попытался установить их программное обеспечение локально на моем Linux Box. Я обнаружил, что некоторые API в какой-то библиотеке Python изменились, и поэтому он не работал. Я немного знаю Python, поэтому я не знал, как решить проблему, и версия с открытым исходным кодом больше не поддерживается и не обновляется.

Итак, мы подумали, что должны были заплатить за поддержку, а затем мы узнали о Pootle. Pootle — это веб-приложение с открытым исходным кодом, оно также написано на Python и основано на Django. Он используется Mozilla и OpenOffice.org и все еще разрабатывается и поддерживается. Некоторые API для взаимодействия с ним скоро будут выпущены, но мы можем установить его на нашем сервере и управлять им с помощью инструмента командной строки.

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

Конфигурация Pootle

Я установил Pootle, как описано здесь http://docs.translatehouse.org/projects/pootle/en/stable-2.5.0/server/index.html#installation . У меня была куча тривиальных проблем, так как на нашем сервере был старый дистрибутив Linux и потому что файл конфигурации отличается, если вы используете django 1.3, но в конце концов это сработало.

После этого Pootle был запущен на нашем сервере, мы создали проект с английским в качестве основного языка и итальянским, португальским и китайским в качестве целевых языков. Мы добавили итальянский, потому что команда разработчиков находится в Италии.

Pootle может полагаться на базу данных для обработки переводов, но он также может считывать данные из файловой системы и синхронизироваться с ними. Таким образом , я создал простое приложение Java , что искали все Bundle.properties в нашем приложении NetBeans RCP и скопированный в собственной директории ( ен стоит на английском языке и является языком по умолчанию или язык шаблонов) нашего вновь созданного проекта. Тогда это приложение запускается

pootle
–config=/etc/pootle.conf update_stores –keep --project=myproject

Эта команда заставляет Pootle считывать содержимое файлов в свою базу данных. Тогда мое приложение запускается

pootle
–config=/etc/pootle.conf  update_against_templates –keep
--project=myproject

Эта команда синхронизирует другие языки с английским шаблоном. Документацию можно найти здесь:

http://docs.translatehouse.org/projects/pootle/en/stable-2.5.0/server/commands.html#managing-pootle-projects .

Наши файлы Bundle.properties (файлы, которые Java использует для интернационализации) переименовываются в packagename.properties, например org.scantamburlo.i18ntest. свойства

Теперь пользователь может начать перевод после входа на наш сервер.

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

pootle
–config=/etc/pootle.conf  sync_stores  --overwrite

Это копирует данные, хранящиеся в базе данных Pootle, в файлы. Каждый язык имеет свой собственный каталог, поэтому если у нас есть файл с именем org.scantamburlo.i18ntest. в свойствах каталога en , внутри каталогов it , zh_CN и pt_BR будет файл с таким же именем .

I18N упрощен с NetBeans

Мы всегда следовали хорошей практике программирования, чтобы поместить все строки, которые будут визуализированы пользователю, в файлы свойств. Язык по умолчанию — английский, а файл свойств содержит пары, такие как MyPanel.MyLabel.text = Text на этикетке . Если мы хотим предоставить перевод на итальянский язык, нам просто нужно создать еще один файл, содержащий те же ключи с текстом на итальянском языке, как MyPanel.MyLabel.text = Testo sulla Label . По умолчанию в NetBeans эти файлы называются Bundle.properties, и для каждого пакета существует один файл, файл, содержащий переводы, называется Bundle_it_IT.properties для итальянского, на котором говорят в Италии (для вашей информации, на итальянском также говорят в Швейцарии).

Когда мы хотим получить значение строки, мы используем org.openide.util. Класс NbBundle , он имеет несколько полезных статических методов для извлечения переведенных строк, таких как:

NbBundle.getMessage (MyPanel.class, «MyPanel.MyLabel.text»));

NetBeans сначала проверит язык, который исходит из Locale.getDefa u lt () , и, если он не найден, он приложит некоторые усилия, чтобы найти ближайший; например, если перевод в Bundle_it_IT.properties не найден, он будет искать в Bundle_it.properties и, наконец, в Bundle.properties .

Создание модулей для переводов

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

Самый простой способ обеспечить интернационализацию — поместить переведенные файлы свойств в пакет исходного файла. Например, мы копируем переведенные файлы из каталога Pootle it ( он означает итальянский) в соответствующий пакет java и переименовываем файл Bundle_it_IT.properties . То же самое для других языков, если бы это был бразильский португальский, файл был бы Bundle_pt_BR.properties . Этот метод имеет существенный недостаток: каждый раз, когда мы обновляем наши переводы, нам приходилось публиковать весь модуль.

К счастью, мы работаем на платформе NetBeans, и она позволяет распределять переводы в другом модуле, как указано здесь:

https://platform.netbeans.org/articles/how-to-do-localization.html .

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

Один намек поступил от руководителя нашего проекта и от этого поста http://blogs.kiyut.com/tonny/2008/08/06/netbeans-platform-localization-as-plugins/#.Uf6td21GaHM : мы можем создать модуль для каждого язык, итальянский, китайский и португальский и распространять его отдельно.

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

  • Прежде всего, мы создали модуль для языка, например, вы можете дать ему кодовое имя org.scantamburlo.translation.it или что угодно.

  • Создайте эти каталоги в нем <module_directory> release \ modules \ locale.

  • Для каждого модуля, который вы хотите перевести, создайте файл jar в этом каталоге, файл jar должен быть назван как кодовая база модуля с точками, замененными символом «-», подчеркиванием, кодом для языка и «.jar» , Например, чтобы перевести модуль с codenamebase org.scantamburlo.i18ntest на итальянский язык, вы должны создать файл с именем org-scantamburlo-i18ntest_it_IT.jar . Этот jar-файл должен содержать те же пакеты, что и исходный модуль, и там, где файл Bundle.properties присутствует в исходном модуле, Bundle_it_IT.properties , конечно, он должен содержать строки перевода.

  • Модули должны быть перезапущены, поэтому щелкните правой кнопкой мыши на них, выберите «Свойства» → «Упаковка» и установите флажок «Требуется перезагрузка при установке».

  • Если ваш модуль принадлежит к набору модулей, добавьте эту строку в project.properties nbm.target.cluster = <name_of_the_cluster>

  • Если вы хотите проверить перевод, и языковой стандарт по умолчанию отличается от итальянского / итальянского, добавьте его в свойство default_options — locale it: IT , обратите внимание на двоеточие вместо подчеркивания.

На этом этапе после установки модуля и перезапуска приложения вы увидите примененный перевод.

В качестве первого шага в нашем RCP мы решили перевести только текст, но платформа Netbeans предлагает возможность добавлять интернационализированные записи в слой, а также интернационализировать изображения.

Весь процесс отправки файлов свойств в Pootle и создания модулей, содержащих переводы, был автоматизирован с помощью Jenkins ( http://jenkins-ci.org/ ), и он будет запущен в производство в следующем месяце.

Спасибо моим коллегам Маттео Ди Джовинаццо и Паоло Репеле за помощь в этом проекте!

Я приложил рабочий пример.