动手搭建翻译协作平台

Author Avatar
dujun05 10月 21, 2021
本文总阅读量
  • 在其它设备中阅读本文章

传统翻译过程是跑出项目中的中文文件,将文件发给翻译人员,翻译完成传回研发,研发再替换到项目中。(一般给翻译人员的是 excel 或者 txt,还需要脚本进行转换至 json 之类的格式);

进一步,待翻译文件被上传至在线文档,多名翻译人员可以同时翻译;

更进一步,使用专门的翻译协作平台, 如 Transifex, Lokalise, Crowdin,这些平台基本都集成了 github,gitlab 等仓库,也支持 api 访问。

因这些平台收费都不菲(企业 5000 刀/年),今天介绍的是开源的 weblate,基于其开源项目可以自行搭建协作平台。

安装

  1. 安装 docker,docker-compose
sudo yum install docker
sudo curl -L https://github.com/docker/compose/releases/download/1.21.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
  1. 下载 weblate
git clone https://github.com/WeblateOrg/docker-compose.git weblate-docker
cd weblate-docker && vi docker-compose.override.yml

创建 docker-compose.override.yml 文件

version: '3'
services:
    weblate:
        ports:
        - 80:8080
        environment:
        // 发送邮件邮箱
        WEBLATE_EMAIL_HOST: smtp.example.com
        // 邮箱用户名
        WEBLATE_EMAIL_HOST_USER: user
        // 邮箱密码
        WEBLATE_EMAIL_HOST_PASSWORD: ***
        // 必须配置才能通过weblate.example.com访问
        WEBLATE_ALLOWED_HOSTS: weblate.example.com
        // 管理员密码
        WEBLATE_ADMIN_PASSWORD: ***
        // 站点域名
        WEBLATE_SITE_DOMAIN: weblate.example.com
        // 管理员邮箱
        WEBLATE_ADMIN_EMAIL: admin@example.com
// 启动
docker-compose up
// 停止
docker-compose down

附上官方安装步骤

集成 git

  1. 将 ssh 密钥添加至 git 仓库

  2. 在组件的设置里配置 git 地址

  3. 设置文件模板

官方版本控制集成文档

api 访问

如果对 weblate 的安全持有怀疑,weblate 也提供了 api 访问

  1. 上传
    官方文档给了示例:
curl -X POST \
    -F file=@strings.xml \
    -H "Authorization: Token TOKEN" \
    http://example.com/api/translations/hello/android/cs/file/

但是尝试了多次都失败了,一度怀疑是配置有问题,后来发现是缺少了 method,加上method: replace就可以了

下面是用 node 实现的关键步骤

const program = require("commander");
const axios = require("axios");
const fsExtra = require("fs-extra");
const FormData = require("form-data");

// 获取相关参数
program
  .option("-p, --path <path>", "翻译文件的路径")
  .option("-o, --organization <organization>", "所属组织")
  .parse(process.argv);

// 创建axiosBase
const axiosBase = axios.create({
  baseURL: "http://xxx/api/",
  headers: {
    "Content-Disposition": "attachment",
    "Content-Type": "multipart/form-data",
    Authorization: "Token xxx",
  },
});

// 获取所有需要上传的文件
const files = fsExtra.readdirSync(uploadPath);

// 组装formdata
let formData = new FormData();
formData.append("method", "replace");
formData.append("file", file);
formData.append("filename", fileName);
const headers = formData.getHeaders();

// 上传文件
await axiosBase.post(
  `translations/${organization}/${componentName}/${fileLang}/file/`,
  formData,
  { headers }
);
  1. 下载
    翻译人员在平台上翻译完成后,再通过脚本将文案拉到项目中。
// 获取目标文件夹中所有需要下载的语言
const fileList = await fsExtra.readdirSync(outputPath);

// 下载所有语言的文件
fileList.forEach(async (file) => {
  let [fileName] = file.split(".");
  const res = await axiosBase(
    `translations/${organization}/${componentName}/${fileName}/file/`
  );
});

// 将文件写入本地
await fsExtra.outputFileSync(
  `${outputPath}/${fileName}.json`,
  JSON.stringify(res.data, null, 2),
  "utf8"
);

如果国际化使用的是 kiwi,也可以支持,大致思路就是将导出的 txt 转为 json 再上传,翻译完成,下载后再转为 txt,关键包为 d3-dsv。