Skip to content

Commit

Permalink
Support for BQU Quest translations (#3)
Browse files Browse the repository at this point in the history
* Add bqu builder
  • Loading branch information
tier940 authored Jun 15, 2024
1 parent f92b7cf commit 06e9a1c
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 101 deletions.
37 changes: 17 additions & 20 deletions .github/workflows/deploy_questbook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,30 @@ permissions:
on:
workflow_dispatch:
inputs:
choice_language:
description: 'Language'
default: EN-US, ZH
required: true
questbook_branch:
description: 'QuestBook branch'
type: choice
default: 'main'
options:
- 'main'
- 'preview'
modpack_version:
description: 'Modpack version'
required: true
questbook_version:
description: 'QuestBook version'
required: true

env:
MODPACK_VERSION: "v${{ github.event.inputs.modpack_version }}"
QUESTBOOK_VERSION: "v${{ github.event.inputs.questbook_version }}"
NAME: "GTExpert2"
FULL_NAME: "GTExpert2-v${{ github.event.inputs.modpack_version }}-ftbquests-${{ github.event.inputs.questbook_version }}"

jobs:
deploy:
runs-on: ubuntu-latest
strategy:
matrix:
language: ['EN-US', 'ZH']
language: ["${{ github.event.inputs.choice_language }}"]
steps:
- name: Checkout
uses: actions/checkout@v4
Expand All @@ -37,13 +42,8 @@ jobs:
exit 1
fi
- name: Download quest zip
run: |
wget -O questbook.zip https://github.com/GTModpackTeam/GregTech-Expert-2-FTBQuestBook/archive/refs/heads/main.zip
unzip questbook.zip
mkdir ./ftbquests/
mv -vf ./GregTech-Expert-2-FTBQuestBook-main/* ./ftbquests/
rm -rf ./GregTech-Expert-2-FTBQuestBook-main/ ./questbook.zip
- name: Download quest json
run: wget -O ./DefaultQuests.json https://raw.githubusercontent.com/GTModpackTeam/GregTech-Expert-2/${{ github.event.inputs.questbook_branch }}/overrides/config/betterquesting/DefaultQuests.json

- name: Setup Python
uses: actions/setup-python@v5
Expand All @@ -60,11 +60,9 @@ jobs:
env:
DEEPL_AUTH_KEY: ${{ secrets.DEEPL_AUTH_KEY }}
TARGET_LANG_CODE: ${{ matrix.language }}
run: python ./buildtools/questbook/translate.py

- name: Archive Release
run: |
zip -r ./${{ env.FULL_NAME }}-${{ matrix.language }}.zip ./ftbquests-tl-${{ matrix.language }}/
mkdir ./bqu/
python ./buildtools/questbook/translate.py
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
Expand All @@ -73,5 +71,4 @@ jobs:
draft: false
prerelease: false
generate_release_notes: true
files: |
./${{ env.FULL_NAME }}-*.zip
files: ./bqu/DefaultQuests_${{ matrix.language }}.json
9 changes: 5 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
ftbquests/
ftbquests-tl/
ftbquests-new/
out/
DefaultQuests.json
bqu/
bqu-tl/
bqu-new/
out/
6 changes: 3 additions & 3 deletions buildtools/questbook/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
## How to translate

1. First, you need to download the [latest version](https://github.com/GTModpackTeam/GTE2-Translations/releases)
2. Download the `GTExpert2-<modpack_version>-ftbquests-<questbook_version>.zip`
2. Download the `DefaultQuests_lang.json`
3. Open the GTE2 instance folder
4. Remove the `normal` folder from the `config/ftbquests` folder
5. Unzip the `normal` in the downloaded zip file into the `config/ftbquests` folder
4. Remove the `DefaultQuests.json` file from the `config/betterquesting` folder
5. Download the `DefaultQuests_lang.json` file to the `config/betterquesting` folder and rename it to `DefaultQuests.json`
6. Run the instance and enjoy the game!

## TODO
Expand Down
84 changes: 84 additions & 0 deletions buildtools/questbook/bak_ftbq/translate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import deepl
import re
import os

source_path = "ftbquests"
target_path = "ftbquests-tl-" + os.environ["TARGET_LANG_CODE"]

auth_key = os.environ["DEEPL_AUTH_KEY"]

# Language code can be known in https://www.deepl.com/docs-api/general/get-languages
target_lang_code = os.environ["TARGET_LANG_CODE"]

# In some area on this earth, you should set a proper api server site at first.
server_url = "https://api-free.deepl.com"

tl = translator = deepl.Translator(auth_key, server_url=server_url)

# this matches every "" sequence that contains a non-ascii unicode character
# also accounts for escaped \" groups inside the double quotes
match_jap = r'"((?:\\.|[^\\"\n\r])*)[\u0080-\uffff]((?:\\.|[^\\"\n\r])*)"'


# replace matches of the r regex in s with f(match)
def regex_replace(r, s, f):
new = ""
start = 0
for m in re.finditer(r, s):
end, newstart = m.span()
new += s[start:end]
new += f(m.group())
start = newstart
new += s[start:]
return new


def copy_structure(src, dst):
for dirpath, dirnames, _ in os.walk(src):
for d in dirnames:
os.makedirs(
os.path.join(dst, *dirpath.split(os.path.sep)[1:], d),
exist_ok=True,
)


def translate(s):
# un-escape the string so that it doesnt confuse deepl
res = s[1:-1].replace('\\"', '"')
res = tl.translate_text(
res, source_lang="JA", target_lang=target_lang_code , preserve_formatting=True
).text
return '"' + res.replace('"', '\\"') + '"'


def create_file_set(path, f=lambda s: s.endswith(".snbt")):
res = set()
for dirpath, _, filenames in os.walk(path):
for filename in filenames:
if not f(filename):
continue
file = os.path.join(dirpath, filename)
if os.path.isfile(file):
res.add(os.path.join(*file.split(os.path.sep)[1:]))
return res


def main():
copy_structure(source_path, target_path)
ofiles = create_file_set(source_path)
tlfiles = create_file_set(target_path)
to_translate = ofiles - tlfiles
if not to_translate:
print("translation seems up to date")
return
for fp in to_translate:
with open(os.path.join(source_path, fp), "r", encoding='utf-8') as f:
s = f.read()
print(f"translating {fp}...")
translated = regex_replace(match_jap, s, translate)
with open(os.path.join(target_path, fp), "x", encoding='utf-8') as tf:
tf.write(translated)
print("done")


main()
File renamed without changes.
2 changes: 1 addition & 1 deletion buildtools/questbook/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
deepl
deepl==1.18.0
106 changes: 33 additions & 73 deletions buildtools/questbook/translate.py
Original file line number Diff line number Diff line change
@@ -1,84 +1,44 @@
import deepl
import re
import os

source_path = "ftbquests"
target_path = "ftbquests-tl-" + os.environ["TARGET_LANG_CODE"]

auth_key = os.environ["DEEPL_AUTH_KEY"]
import json
import deepl

# Language code can be known in https://www.deepl.com/docs-api/general/get-languages
target_lang_code = os.environ["TARGET_LANG_CODE"]

# You should set your deepl auth key in your environment variable.
auth_key = os.environ["DEEPL_AUTH_KEY"]

# In some area on this earth, you should set a proper api server site at first.
server_url = "https://api-free.deepl.com"

tl = translator = deepl.Translator(auth_key, server_url=server_url)

# this matches every "" sequence that contains a non-ascii unicode character
# also accounts for escaped \" groups inside the double quotes
match_jap = r'"((?:\\.|[^\\"\n\r])*)[\u0080-\uffff]((?:\\.|[^\\"\n\r])*)"'


# replace matches of the r regex in s with f(match)
def regex_replace(r, s, f):
new = ""
start = 0
for m in re.finditer(r, s):
end, newstart = m.span()
new += s[start:end]
new += f(m.group())
start = newstart
new += s[start:]
return new


def copy_structure(src, dst):
for dirpath, dirnames, _ in os.walk(src):
for d in dirnames:
os.makedirs(
os.path.join(dst, *dirpath.split(os.path.sep)[1:], d),
exist_ok=True,
)


def translate(s):
# un-escape the string so that it doesnt confuse deepl
res = s[1:-1].replace('\\"', '"')
res = tl.translate_text(
res, source_lang="JA", target_lang=target_lang_code , preserve_formatting=True
).text
return '"' + res.replace('"', '\\"') + '"'


def create_file_set(path, f=lambda s: s.endswith(".snbt")):
res = set()
for dirpath, _, filenames in os.walk(path):
for filename in filenames:
if not f(filename):
continue
file = os.path.join(dirpath, filename)
if os.path.isfile(file):
res.add(os.path.join(*file.split(os.path.sep)[1:]))
return res

def load_json_file(file_path):
with open(file_path, 'r', encoding='utf-8') as file:
return json.load(file)

def translate_text(text, translator, source_lang='JA', target_lang=target_lang_code):
if not text.strip():
return text
return translator.translate_text(text, source_lang=source_lang, target_lang=target_lang).text

def translate_json_values(json_data, translator, keys_to_translate=['name:8', 'desc:8']):
for quest_id, quest_data in json_data.get('questDatabase:9', {}).items():
for key in keys_to_translate:
if key in quest_data.get('properties:10', {}).get('betterquesting:10', {}):
original_text = quest_data['properties:10']['betterquesting:10'][key]
if original_text:
translated_text = translate_text(original_text, translator)
quest_data['properties:10']['betterquesting:10'][key] = translated_text
return json_data

def save_json_file(file_path, data):
with open(file_path, 'w', encoding='utf-8') as file:
json.dump(data, file, ensure_ascii=False, indent=2)

def main():
copy_structure(source_path, target_path)
ofiles = create_file_set(source_path)
tlfiles = create_file_set(target_path)
to_translate = ofiles - tlfiles
if not to_translate:
print("translation seems up to date")
return
for fp in to_translate:
with open(os.path.join(source_path, fp), "r", encoding='utf-8') as f:
s = f.read()
print(f"translating {fp}...")
translated = regex_replace(match_jap, s, translate)
with open(os.path.join(target_path, fp), "x", encoding='utf-8') as tf:
tf.write(translated)
print("done")

translator = deepl.Translator(auth_key, server_url=server_url)
json_data = load_json_file("./DefaultQuests.json")
translated_json_data = translate_json_values(json_data, translator)
save_json_file("./bqu/DefaultQuests_" + target_lang_code + ".json", translated_json_data)

main()
if __name__ == "__main__":
main()

0 comments on commit 06e9a1c

Please sign in to comment.