Skip to content

Commit

Permalink
🎉 init(superset): 4.1.1-py311
Browse files Browse the repository at this point in the history
  • Loading branch information
luting committed Nov 22, 2024
1 parent 4c1f1aa commit 160dd33
Show file tree
Hide file tree
Showing 11 changed files with 47,583 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
generate_locales.py
generate_messages.py
.gitea
locales
target
4 changes: 2 additions & 2 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: ci
name: DockerHub Publish

on:
workflow_dispatch:
Expand All @@ -12,7 +12,7 @@ on:
- 'main'

jobs:
docker:
build-push:
runs-on: ubuntu-latest
steps:
-
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target
23 changes: 23 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
FROM apache/superset:4.1.1-py311

COPY messages.json /app/superset/translations/zh/LC_MESSAGES/messages.json
COPY messages.po /app/superset/translations/zh/LC_MESSAGES/messages.po

USER root
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &&\
export DEBIAN_FRONTEND=noninteractive &&\
apt-get update &&\
apt-get -y install --no-install-recommends --no-install-suggests wget pkg-config gcc &&\
apt-get -y clean && rm -rf /var/lib/apt/lists/* &&\
# 安装数据库驱动
pip install psycopg2 mysqlclient &&\
# 默认语言
sed -i "s/*BABEL_DEFAULT_LOCALE*/BABEL_DEFAULT_LOCALE = \"zh\"/" /app/superset/config.py &&\
sed -i "s/LANGUAGES = {}/LANGUAGES = {\"zh\": {\"flag\": \"cn\", \"name\": \"简体中文\"}, \"en\": {\"flag\": \"us\", \"name\": \"English\"}}/" /app/superset/config.py &&\
# 清理不需要的翻译
cd /app/superset/translations &&\
rm -rf ar de es fr it ja ko nl pt pt_BR ru sk sl tr uk zh-TW &&\
# 翻译
pybabel compile -d /app/superset/translations || true

USER superset
89 changes: 89 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Superset 汉化/中文版

![Version](https://img.shields.io/docker/v/lutinglt/superset-zh/latest?arch=amd64&sort=semver&color=066da5) ![Docker Pulls](https://img.shields.io/docker/pulls/lutinglt/superset-zh.svg?style=flat&label=pulls&logo=docker) ![Docker Size](https://img.shields.io/docker/image-size/lutinglt/superset-zh/latest?color=066da5&label=size) ![License](https://img.shields.io/github/license/lutinglt/superset-zh)

## 简介

[PR: 29476](https://github.com/apache/superset/pull/29476) 这个提交中删除了大量的中文翻译,导致 Superset 的中文翻译质量大幅下降, 在这次提交后便没有人再对中文翻译进行维护。

本项目基于 [PR: 27922](https://github.com/apache/superset/pull/27922) 的最后一次中文翻译提交,用 Python 构建了翻译脚本, 脚本改变了汉化步骤, 先生成 messages.json, 再通过 json 生成 messages.po, 此过程修复了一些翻译文件无法正常生效的问题.

## 使用方法

### Docker 镜像

#### 下载镜像

基于官方镜像生成, 修复了汉化问题, 仅保留中文和英文两种语言并且默认显示中文, 默认时区上海, 并添加了 Postgres 和 MySQL 数据库驱动, 其他配置与官方镜像相同.

```bash
docker pull lutinglt/superset-zh
```

#### 手动构建

FROM 关键字后替换自己需要的官方镜像标签

```bash
git clone https://github.com/lutinglt/superset-zh.git
cd superset-zh
docker build -t lutinglt/superset-zh .
```

### 手动汉化

找到 Superset 安装目录下的 `translations` 目录, 找到 `zh/LC_MESSAGES` 目录, 直接将项目仓库里的 `messages.json``messages.po` 文件复制到 `zh/LC_MESSAGES` 目录下, 然后运行:

```bash
# 替换成自己的安装目录下的 translations 目录
pybabel compile -d superset/translations
```

重启 Superset 查看汉化效果.

> [!IMPORTANT]
>
> config.py 里的 `BABEL_DEFAULT_LOCALE` 变量会影响标题栏的汉化, 默认为 `en`, 修改为 `zh` 重新编译即可.
> [!IMPORTANT]
>
> config.py 里的 `LANGUAGES` 变量为空会关闭语言选择框, 默认为空, 参考配置:
```python
BABEL_DEFAULT_LOCALE = "zh"
LANGUAGES = {
"zh": {"flag": "cn", "name": "简体中文"},
"en": {"flag": "us", "name": "English"},
}
```

> [!NOTE]
>
> superset_config.py 会覆盖 config.py 里的配置, 优先级更高.
> [!TIP]
>
> Superset 2.1.0 之后安装的默认安全选项更为严格, 部署后登录不上, 或无法启动推荐添加以下配置
>
> ```python
> SECRET_KEY = 'superset' # 安全密钥, 启动必须进行配置
> WTF_CSRF_ENABLED = False # 关闭 CSRF 验证
> TALISMAN_ENABLED = False # 关闭 TALISMAN 安全选项
> CONTENT_SECURITY_POLICY_WARNING = False # 关闭内容安全策略警告
> ```
## 脚本说明
### `generate_locales.py`
基于 Superset 项目下的 `superset/translations/messages.pot``superset/translations/zh/LC_MESSAGES/messages.po` 生成最新的需要翻译的内容, 然后取本项目下 `messages.json` 已翻译的部分覆盖需要翻译的内容, 生成全部翻译条目(包含未翻译)和筛选出未翻译的条目的 json 文件, 进行手动校验翻译过程, 方便补充新翻译和修改已翻译内容, 具体查看脚本文档注释内容.
### `generate_messages.py`
根据已经翻译的内容生成 Superset 前端需要的 `messages.json``messages.po`, 具体查看脚本文档注释内容.
## 贡献
欢迎提交 PR, 修复汉化问题, 补充汉化内容或者优化翻译脚本.
汉化贡献仅需提交最新的 `messages.json` 文件即可
51 changes: 51 additions & 0 deletions generate_locales.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/bin/python
# -*- coding:utf-8 -*-
"""
所有文件统一使用 utf-8 编码, 行尾统一使用 LF
运行前请下载最新的 messages.pot 和 messages.po 文件, 并放置在 locales 目录下 (鉴于网络原因, 不使用脚本请手动下载)
https://github.com/apache/superset/blob/master/superset/translations/messages.pot
https://github.com/apache/superset/blob/master/superset/translations/zh/LC_MESSAGES/messages.po
先在项目的当前目录运行该脚本, 生成 target 待翻译目录
target/tmp/messages.json : 保存所有翻译, 用于修改现有翻译(如果补充翻译会被filter_messages.json覆盖)
target/tmp/filter_messages.json : 保存未翻译的, 用于补充翻译
target/tmp/plural_messages.json : 保存复数翻译, 标记文件, 请勿修改
完善翻译后, 在项目的当前目录运行 generate_messages.py
"""

import json
import os

import polib
from babel.messages.frontend import CommandLineInterface

if __name__ == "__main__":
# 根据最新的翻译模版 messages.pot 生成新的 messages.po
argv = ["pybabel", "init", "-i", "locales/messages.pot", "-d", "target/locales", "-l", "en"]
CommandLineInterface().run(argv)

# 读取旧的 messages.json
with open("messages.json", "r", encoding="utf-8") as f:
old_trans = json.load(f)["locale_data"]["superset"]
del old_trans[""]

# 读取新的 messages.po
po = polib.pofile("target/locales/en/LC_MESSAGES/messages.po")
new_trans = {entry.msgid: entry.msgstr for entry in po}
plural_trans = {entry.msgid: entry.msgid_plural for entry in po if entry.msgstr_plural}

# 新的 messages.po 合并新的中文 messages.po 和旧的 messages.json
zh_po = polib.pofile("locales/zh/LC_MESSAGES/messages.po")
new_trans.update({zh_entry.msgid: zh_entry.msgstr for zh_entry in zh_po})
new_trans.update(old_trans)

# 生成新的 messages.json
os.makedirs("target/tmp", exist_ok=True)
with open("target/tmp/messages.json", "w", encoding="utf-8") as f:
json.dump(new_trans, f, ensure_ascii=False, indent=2, sort_keys=True)

with open("target/tmp/filter_messages.json", "w", encoding="utf-8") as f:
filter_trans = {k: v for k, v in new_trans.items() if v == "" or v == [""]}
json.dump(filter_trans, f, ensure_ascii=False, indent=2, sort_keys=True)

with open("target/tmp/plural_messages.json", "w", encoding="utf-8") as f:
json.dump(plural_trans, f, ensure_ascii=False, indent=2, sort_keys=True)
58 changes: 58 additions & 0 deletions generate_messages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/bin/python
# -*- coding:utf-8 -*-
"""
该脚本运行后,会生成 target/messages.json, 并将 target/messages.json 转换为 target/messages.po
检查无误后, 请使用默认配置的 prettier 格式化 target/messages.json
手动覆盖根目录下的 messages.json 和 messages.po, 之后提交代码
"""

import json

import polib

if __name__ == "__main__":
# 读取翻译文件
with open("target/tmp/messages.json", "r", encoding="utf-8") as f:
new_trans: dict[str, str | list[str]] = json.load(f)

# 读取翻译补充文件
with open("target/tmp/filter_messages.json", "r", encoding="utf-8") as f:
new_trans.update(json.load(f))

# 读取复数翻译标记文件
with open("target/tmp/plural_messages.json", "r", encoding="utf-8") as f:
plural_trans: dict[str, str] = json.load(f)

# 读取现有的翻译文件
with open("messages.json", "r", encoding="utf-8") as f:
trans: dict = json.load(f)
trans["locale_data"]["superset"].update(new_trans)
# superset 前端翻译的值如果是字符串, 只会显示第一个字符, 所以需要转换为列表
for k, v in trans["locale_data"]["superset"].items():
if isinstance(v, str):
trans["locale_data"]["superset"][k] = [v]

# 生成 messages.json
with open("target/messages.json", "w", encoding="utf-8") as f:
json.dump(trans, f, ensure_ascii=False, indent=2, sort_keys=True)

# 生成 messages.po
zh_po = polib.pofile("locales/zh/LC_MESSAGES/messages.po")
po = polib.POFile()
po.metadata = zh_po.metadata
po_trans = {k: v[0] if isinstance(v, list) else v for k, v in trans["locale_data"]["superset"].items()}
del po_trans[""]
for msgid, msgstr in po_trans.items():
if msgid in plural_trans:
entry = polib.POEntry(
msgid=msgid,
msgid_plural=plural_trans[msgid],
msgstr_plural={0: msgstr},
)
else:
entry = polib.POEntry(
msgid=msgid,
msgstr=msgstr,
)
po.append(entry)
po.save("target/messages.po")
Loading

0 comments on commit 160dd33

Please sign in to comment.