From 97309599f144ce7a5e9a048329b09c2fae2d1c07 Mon Sep 17 00:00:00 2001 From: Terry Geng Date: Sun, 12 Jul 2020 14:29:50 +0800 Subject: [PATCH] feat: Add translation populating procedure for the web interface. --- .drone.yml | 5 +- .gitignore | 2 +- README.md | 5 +- interface.py | 5 +- lang/en_US.json | 77 ++++++++ mumbleBot.py | 1 + templates/translate.py | 58 ++++++ variables.py | 2 + web/js/main.mjs | 2 +- .../{index.html => index.template.html} | 170 +++++++++--------- ...ed_token.html => need_token.template.html} | 14 +- web/webpack.config.cjs | 8 +- 12 files changed, 239 insertions(+), 110 deletions(-) create mode 100755 templates/translate.py rename web/templates/{index.html => index.template.html} (79%) rename web/templates/{need_token.html => need_token.template.html} (71%) diff --git a/.drone.yml b/.drone.yml index 5e0fae1..7008260 100644 --- a/.drone.yml +++ b/.drone.yml @@ -7,17 +7,18 @@ steps: image: node commands: - (cd web && npm install && npm run build) + - (cd templates/ && ./translate.py) - name: deploy-testing image: debian commands: + - (cd lang && ./sync_translation.py --client $TRADUORA_W_CLIENT --secret $TRADUORA_W_SECRET --push) - apt-get -qq update && apt-get -qq install git > /dev/null - sed -i 's/target_version = git/target_version = testing/' configuration.default.ini - version=$(git rev-parse HEAD) - echo "current git commit is $version" - echo $version > /mnt/botamusique/testing-version - sed -i "s/version = 'git'/version = '$version'/" mumbleBot.py - - (cd lang && ./sync_translation.py --client $TRADUORA_W_CLIENT --secret $TRADUORA_W_SECRET --push) - rm -rf .git* - rm -rf web - mkdir /tmp/botamusique @@ -51,6 +52,7 @@ steps: - name: deploy-stable image: debian commands: + - (cd lang && ./sync_translation.py --client $TRADUORA_W_CLIENT --secret $TRADUORA_W_SECRET --push) - apt-get -qq update && apt-get -qq install jq curl git pandoc > /dev/null - sed -i 's/target_version = git/target_version = stable/' configuration.default.ini - git fetch --tags @@ -59,7 +61,6 @@ steps: - echo $version > /mnt/botamusique/version - sed -i "s/version = 'git'/version = '$version'/" mumbleBot.py - curl --silent "https://api.github.com/repos/azlux/botamusique/releases/latest" | jq -r '.body' | pandoc --from gfm --to html - --output - > /mnt/botamusique/changelog - - (cd lang && ./sync_translation.py --client $TRADUORA_W_CLIENT --secret $TRADUORA_W_SECRET --push) - rm -rf .git* - rm -rf web - mkdir /tmp/botamusique diff --git a/.gitignore b/.gitignore index e649d17..54ac0c2 100644 --- a/.gitignore +++ b/.gitignore @@ -116,7 +116,7 @@ tmp/ *.db -templates/* +templates/*.html # Pycharm .idea/ diff --git a/README.md b/README.md index dfed6a5..a26fd8e 100644 --- a/README.md +++ b/README.md @@ -91,9 +91,8 @@ cd botamusique python3 -m venv venv venv/bin/pip install wheel venv/bin/pip install -r requirements.txt -cd web -npm install -npm run build +(cd web && npm install && npm run build) +(cd templates/ && ./translate.py) ``` diff --git a/interface.py b/interface.py index f9135f3..2f1144f 100644 --- a/interface.py +++ b/interface.py @@ -169,7 +169,7 @@ def requires_auth(f): bad_access_count[request.remote_addr] = 1 log.info(f"web: bad token from ip {request.remote_addr}.") - return render_template('need_token.html', + return render_template(f'need_token.{var.language}.html', name=var.config.get('bot', 'username'), command=f"{var.config.get('commands', 'command_symbol')[0]}{var.config.get('commands', 'requests_webinterface_access')}") @@ -225,7 +225,7 @@ def get_all_dirs(): @web.route("/", methods=['GET']) @requires_auth def index(): - return open('templates/index.html', "r").read() + return open(f"templates/index.{var.language}.html", "r").read() @web.route("/playlist", methods=['GET']) @@ -554,7 +554,6 @@ def library_info(): tags = var.music_db.query_all_tags() max_upload_file_size = util.parse_file_size(var.config.get("webinterface", "max_upload_file_size", fallback="30MB")) - print(get_all_dirs()) return jsonify(dict( dirs=get_all_dirs(), upload_enabled=var.config.getboolean("webinterface", "upload_enabled", fallback=True), diff --git a/lang/en_US.json b/lang/en_US.json index db7a6af..3f69588 100644 --- a/lang/en_US.json +++ b/lang/en_US.json @@ -76,5 +76,82 @@ "yt_no_more": "No more results!", "yt_query_error": "Unable to query youtube!", "yt_result": "Youtube query result: {result_table} Use !sl {{indexes}} to play the item you want.
\n!ytquery -n for the next page." + }, + "web": { + "action": "Action", + "add": "Add", + "add_all": "Add All", + "add_radio": "Add Radio", + "add_radio_url": "Add Radio URL", + "add_to_bottom": "Add to bottom", + "add_to_bottom_of_current_playlist": "Add to bottom of current playlist", + "add_to_playlist_next": "Add to playlist right after current song", + "add_url": "Add URL", + "add_youtube_or_soundcloud_url": "Add Youtube or Soundcloud URL", + "are_you_really_sure": "Are you really sure?", + "aria_botamusique_logo": "Botamusique Logo: a person with two headphones, enjoying the music", + "aria_default_cover": "A black square with two eight notes beamed together.", + "aria_empty_box": "A drawing of an empty box.", + "aria_remove_this_song": "Remove this song from the current playlist", + "aria_skip_current_song": "Skip current song and play this song right now", + "aria_skip_to_next_track": "Skip to next track", + "aria_spinner": "A loading spinner", + "aria_warning_of_deletion": "Warning about deletion of files.", + "autoplay": "Autoplay", + "browse_music_file": "Browse Music file", + "cancel": "Cancel", + "cancel_upload_warning": "Are you really sure?
Click again to abort uploading.", + "change_playback_mode": "Change Playback Mode", + "choose_file": "Choose file", + "clear_playlist": "Clear Playlist", + "close": "Close", + "delete_all": "Delete All", + "delete_all_files": "Delete All Listed Files", + "delete_file_warning": "All files listed here, include files on other pages, will be deleted from your hard-drive.\n Is that what you want?", + "directory": "Directory", + "download_all": "Download All", + "download_song_from_library": "Download song from library", + "edit_submit": "Edit!", + "edit_tags_for": "Edit tags for", + "expand_playlist": "See item on the playlist.", + "file": "File", + "filters": "Filters", + "index": "#", + "keywords": "Keywords", + "keywords_placeholder": "Keywords...", + "mini_player_title": "Now Playing...", + "music_library": "Music Library", + "next_to_play": "Next to play", + "no_tag": "No tag", + "oneshot": "One-shot", + "open_volume_controls": "Open Volume Controls", + "page_title": "botamusique Web Interface", + "pause": "Pause", + "play": "Play", + "playlist_controls": "Playlist controls", + "radio": "Radio", + "radio_url_placeholder": "Radio URL...", + "random": "Random", + "remove_song_from_library": "Remove song from library", + "repeat": "Repeat", + "rescan_files": "Rescan Files", + "skip_track": "Skip Track", + "submit": "Submit", + "tags": "Tags", + "tags_to_add": "Tags to add", + "title": "Title", + "token": "Token", + "token_required": "Token Required", + "token_required_message": "You are accessing the web interface of {{ name }}.\nA token is needed to grant you access.
\nPlease send \"{{ command }}\" to the bot in mumble to acquire one.", + "type": "Type", + "upload_file": "Upload File", + "upload_submit": "Upload!", + "upload_to": "Upload To", + "uploaded_finished": "Uploaded finished!", + "uploading_files": "Uploading files...", + "url": "URL", + "url_path": "Url/Path", + "url_placeholder": "URL...", + "volume_slider": "Volume Slider" } } \ No newline at end of file diff --git a/mumbleBot.py b/mumbleBot.py index 494f14d..75e8420 100644 --- a/mumbleBot.py +++ b/mumbleBot.py @@ -832,6 +832,7 @@ if __name__ == '__main__': if lang not in supported_languages: raise KeyError(f"Unsupported language {lang}") + var.language = lang constants.load_lang(lang) # ====================== diff --git a/templates/translate.py b/templates/translate.py new file mode 100755 index 0000000..86c6f86 --- /dev/null +++ b/templates/translate.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 + +import os +import json +import re +import jinja2 + +default_lang_dict = {} +lang_dict = {} + + +def load_lang(lang): + with open(f"../lang/{lang}.json", "r") as f: + return json.load(f) + + +def tr(option): + try: + if option in lang_dict['web'] and lang_dict['web'][option]: + string = lang_dict['web'][option] + else: + string = default_lang_dict['web'][option] + return string + except KeyError: + raise KeyError("Missed strings in language file: '{string}'. ".format(string=option)) + + +if __name__ == "__main__": + html_files = os.listdir('.') + for html_file in html_files: + match = re.search("(.+)\.template\.html", html_file) + if match is None: + continue + + print(f"Populating {html_file} with translations...") + basename = match[1] + with open(html_file, "r") as f: + html = f.read() + + lang_files = os.listdir('../lang') + lang_list = [] + + default_lang_dict = load_lang("en_US") + + for lang_file in lang_files: + match = re.search("([a-z]{2}_[A-Z]{2})\.json", lang_file) + if match: + lang_list.append(match[1]) + + template = jinja2.Template(html) + + for lang in lang_list: + print(f" - Populating {lang}...") + lang_dict = load_lang(lang) + + with open(f"{basename}.{lang}.html", "w") as f: + f.write(template.render(tr=tr)) + print("Done.") diff --git a/variables.py b/variables.py index 271414c..074d852 100644 --- a/variables.py +++ b/variables.py @@ -23,3 +23,5 @@ bot_logger = None music_folder = "" tmp_folder = "" + +language = "" diff --git a/web/js/main.mjs b/web/js/main.mjs index 7299f47..a461923 100644 --- a/web/js/main.mjs +++ b/web/js/main.mjs @@ -816,7 +816,7 @@ const modal_tag = $('.modal-tag'); const modal_tag_text = $('.modal-tag-text'); function addTagModalShow(_id, _title, _tag_tuples) { - add_tag_modal_title.html('Edit tags for ' + _title); + add_tag_modal_title.html(_title); add_tag_modal_item_id.val(_id); add_tag_modal_tags.empty(); _tag_tuples.forEach(function (tag_tuple) { diff --git a/web/templates/index.html b/web/templates/index.template.html similarity index 79% rename from web/templates/index.html rename to web/templates/index.template.html index c51485c..5f4e5d8 100644 --- a/web/templates/index.html +++ b/web/templates/index.template.html @@ -6,7 +6,7 @@ - botamusique web interface + {{ tr('page_title') }} @@ -18,46 +18,46 @@
Botamusique Logo: a person with two headphones, enjoying the music + alt="{{ tr('aria_botamusique_logo') }}">
-

botamusique Web Interface

+

{{ tr('page_title') }}

-