| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- import os
- import json
- import re
- import subprocess
- import xml.etree.ElementTree as ET
- import requests
- # 可配置支持的语言
- SUPPORTED_LANGUAGES = [
- "zh", "en", "ar"
- ]
- TOLGEE_API_URL = "http://47.236.31.243:8090/api"
- TOLGEE_API_KEY = "tgpak_hbpxgyltnryguy3lonyxiyrtgruta4rroryhiolooe3q"
- PROJECT_ID = "8"
- def find_strings_files(root_dir="."):
- result = []
- for root, dirs, files in os.walk(root_dir):
- normalized_root = root.replace("\\", "/")
- if "lite" in normalized_root or "lite" in files:
- continue
- if "/build/" in normalized_root or normalized_root.endswith("/build"):
- continue
- if "strings.xml" in files and "/src/" in normalized_root:
- full_path = os.path.join(root, "strings.xml")
- rel_path = os.path.relpath(full_path, root_dir).replace("\\", "/")
- result.append({
- "path": rel_path
- })
- return result
- def extract_language_from_path(path):
- """
- 从 Android 的 values[-xx[-rYY]] 路径中提取语言代码。
- - 默认返回 'en'
- - 特殊处理:'in' → 'id'
- """
- match = re.search(r'values(?:-([a-zA-Z-]+))?/', path)
- if match:
- lang = match.group(1)
- if not lang:
- return "en"
- lang = lang.replace("-r", "-")
- if lang == "in":
- return "id"
- return lang
- return "en"
- def generate_tolgee_config():
- files = find_strings_files(".")
- push_files = []
- for f in files:
- lang = extract_language_from_path(f["path"])
- if lang in SUPPORTED_LANGUAGES:
- push_files.append({
- "path": f["path"],
- "language": lang
- })
- config = {
- "apiUrl": TOLGEE_API_URL,
- "apiKey": TOLGEE_API_KEY,
- "projectId": PROJECT_ID,
- "format": "ANDROID_XML",
- "convertPlaceholdersTo": "icu",
- "structureDelimiter": ".",
- "push": {
- "files": push_files
- }
- }
- with open(".tolgeerc", "w", encoding="utf-8") as f:
- json.dump(config, f, indent=2)
- print(f"✅ Tolgee 配置已生成,共 {len(push_files)} 个语言文件")
- def run_tolgee_push():
- print("🚀 正在执行 tolgee push ...")
- try:
- subprocess.run(["tolgee", "push", "--force-mode", "KEEP","--verbose"], check=True)
- print("✅ 推送成功")
- except subprocess.CalledProcessError as e:
- print("❌ 推送失败", e)
- HEADERS = {
- "X-Api-Key": TOLGEE_API_KEY,
- "Content-Type": "application/json"
- }
- def fetch_all_keys():
- dataList = [] #key是name,value是id
- page = 0
- page_size = 1000
- while True:
- url = f"{TOLGEE_API_URL}/v2/projects/{PROJECT_ID}/keys?page={page}&size={page_size}"
- r = requests.get(url, headers=HEADERS)
- if r.status_code != 200:
- print(f"❌ 拉取失败: {r.status_code} -> {r.text}")
- break
- data = r.json()
- # print(data)
- dataList.extend(data['_embedded']['keys'])
- if data['page']['totalPages'] == page +1 : # 最后一页
- break
- page += 1
- print(f"✅ 已拉取 {len(dataList)} 个 Tolgee keys")
- # print(dataList)
- return dataList
- def find_translatable_false_keys():
- result = []
- for root, dirs, files in os.walk("."):
- normalized_root = root.replace("\\", "/")
- if normalized_root.endswith("/res/values") and "strings.xml" in files:
- file_path = os.path.join(root, "strings.xml")
- try:
- tree = ET.parse(file_path)
- root_elem = tree.getroot()
- for elem in root_elem.findall("string"):
- if elem.attrib.get("translatable") == "false":
- result.append(elem.attrib["name"])
- except Exception as e:
- print(f"⚠️ 解析失败:{file_path} -> {e}")
- print(f"🔍 找到 {len(result)} 个 translatable=false 的 key")
- # print(result)
- return result
- def get_key_id_by_name(key_name):
- url = f"{TOLGEE_API_URL}/v2/projects/{PROJECT_ID}/keys?search={key_name}"
- try:
- resp = requests.get(url, headers=HEADERS)
- data = resp.json()
- print(f"🔍 查询 key ID:{key_name} -> {data}")
- if isinstance(data, list) and data:
- return data[0]["id"]
- except Exception as e:
- print(f"❌ 查询 key ID 失败:{key_name} -> {e}")
- return None
- def fetch_language_ids():
- print("📥 拉取 Tolgee 语言信息...")
- url = f"{TOLGEE_API_URL}/v2/projects/{PROJECT_ID}/languages"
- r = requests.get(url, headers=HEADERS)
- if not r.ok:
- print(f"❌ 获取 languages 失败:{r.status_code} -> {r.text}")
- return []
- languages = r.json()['_embedded']['languages']
- print(languages)
- # result = {}
- # for lang in languages:
- # result[lang["tag"]] = lang["id"]
- # print(f"✅ 拉取语言: {result}")
- return {lang["tag"]: lang["id"] for lang in languages}
- def mark_keys_as_disabled(keys: list):
- print(f"🔧 准备禁用 {len(keys)} 个不可翻译的 key")
- all_keys = fetch_all_keys()
- all_languages = fetch_language_ids()
- disabled_lang_ids = [
- lang_id for tag, lang_id in all_languages.items() if tag != 'en'
- ]
- print(f"🔍 禁用语言 ID: {disabled_lang_ids}")
- key_map = {item["name"]: item["id"] for item in all_keys}
- for key in keys:
- key_id = key_map.get(key)
- if not key_id:
- print(f"⚠️ 跳过:{key},未找到 keyId")
- continue
- url = f"{TOLGEE_API_URL}/v2/projects/{PROJECT_ID}/keys/{key_id}/disabled-languages"
- payload = json.dumps({
- "languageIds": disabled_lang_ids
- })
- try:
- resp = requests.request("PUT", url, headers=HEADERS, data=payload)
- if resp.status_code == 200:
- print(f"✅ 已禁用:{key}")
- else:
- print(f"❌ 禁用失败:{key} -> {resp.status_code}: {resp.text}")
- except Exception as e:
- print(f"❌ 异常:{key} -> {e}")
- def main():
- generate_tolgee_config()
- run_tolgee_push()
- # 处理 translatable=false 的 key
- false_keys = find_translatable_false_keys()
- if false_keys:
- mark_keys_as_disabled(false_keys)
- if __name__ == "__main__":
- main()
|