diff --git a/ModAssistant/Localisation/de.xaml b/ModAssistant/Localisation/de.xaml index 5dd640f..6493fa5 100644 --- a/ModAssistant/Localisation/de.xaml +++ b/ModAssistant/Localisation/de.xaml @@ -151,6 +151,10 @@ Installiere Playlist: {0} Titel fehlgeschlagen: {0} [{0} Fehler] Playlist Installation abgeschlossen: {1} + Show OneClick Installer Window + Yes + Close + No Diagnose Log öffnen AppData öffnen @@ -223,6 +227,7 @@ Max tries reached: Skipping {0} Ratelimit hit. Resuming in {0} Download failed: {0} + Done'd Design nicht gefunden, gehe zurück zum Standard Design... diff --git a/ModAssistant/Localisation/en-DEBUG.xaml b/ModAssistant/Localisation/en-DEBUG.xaml index c508210..6124d99 100644 --- a/ModAssistant/Localisation/en-DEBUG.xaml +++ b/ModAssistant/Localisation/en-DEBUG.xaml @@ -111,6 +111,10 @@ {0} Options:InstallingPlaylist {0} Options:FailedPlaylistSong {0} {1} Options:FinishedPlaylist + Options:ShowOCIWindow + Options:OCIWindowYes + Options:OCIWindowClose + Options:OCIWindowNo Options:Diagnostics Options:OpenLogsButton Options:OpenAppDataButton @@ -164,6 +168,7 @@ {0} OneClick:RatelimitSkip {0} OneClick:RatelimitHit {0} OneClick:Failed + OneClick:Done Themes:ThemeNotFound diff --git a/ModAssistant/Localisation/fr.xaml b/ModAssistant/Localisation/fr.xaml index dc28f82..1854794 100644 --- a/ModAssistant/Localisation/fr.xaml +++ b/ModAssistant/Localisation/fr.xaml @@ -157,6 +157,10 @@ Installation de la playlist : {0} Échec de la musique : {0} [{0} échecs] Installation de la playlist terminée : {1} + Show OneClick Installer Window + Yes + Close + No Diagnostic Ouvrir les logs Ouvrir AppData @@ -230,7 +234,8 @@ Maximum de tentatives atteint : {0} passé Limite atteinte. Reprise dans {0} Téléchargement échoué : {0} - + Done'd + Thème non trouvé, passage au thème par défaut... Thème défini sur {0}. diff --git a/ModAssistant/Localisation/it.xaml b/ModAssistant/Localisation/it.xaml index 598f7ea..4e8ea37 100644 --- a/ModAssistant/Localisation/it.xaml +++ b/ModAssistant/Localisation/it.xaml @@ -151,6 +151,10 @@ Installazione Playlist: {0} Installazione canzone fallita: {0} [{0} fails] Installazione playlist terminata: {1} + Show OneClick Installer Window + Yes + Close + No Diagnostica Apri il Log Apri AppData @@ -223,7 +227,8 @@ Max tries reached: Skipping {0} Ratelimit hit. Resuming in {0} Download failed: {0} - + Done'd + Tema non trovato, ritorno al tema predefinito... Tema impostato su {0}. diff --git a/ModAssistant/Localisation/ko.xaml b/ModAssistant/Localisation/ko.xaml index a011cbc..b6e6180 100644 --- a/ModAssistant/Localisation/ko.xaml +++ b/ModAssistant/Localisation/ko.xaml @@ -150,6 +150,10 @@ Installing Playlist: {0} Failed song: {0} [{0} fails] Finished Installing Playlist: {1} + Show OneClick Installer Window + Yes + Close + No 진단 로그 열기 앱데이터 열기 @@ -222,7 +226,8 @@ Max tries reached: Skipping {0} Ratelimit hit. Resuming in {0} Download failed: {0} - + Done'd + 테마를 찾을 수 없어, 기본 테마로 돌아갑니다... {0} 테마로 설정합니다. diff --git a/ModAssistant/Localisation/nl.xaml b/ModAssistant/Localisation/nl.xaml index 5e7333c..1e60ae4 100644 --- a/ModAssistant/Localisation/nl.xaml +++ b/ModAssistant/Localisation/nl.xaml @@ -31,7 +31,7 @@ Geen mod geselecteerd! {0} heeft geen info pagina - + Introductie Welkom bij Mod Assistant Lees deze pagina alstublieft volledig en aandachtig @@ -149,6 +149,10 @@ Afspeellijst installeren: {0} Installatie nummer mislukt: {0} [{0} mislukkingen] Afspeellijst geïnstalleerd: {1} + Show OneClick Installer Window + Yes + Close + No Diagnostiek Open Logs Open AppData @@ -221,7 +225,8 @@ Maximaal aantal pogingen bereikt: {0} word overgeslagen Snelheidslimiet bereikt. Gaat verder over {0} Download mislukt: {0} - + Done'd + Thema niet gevonden, terugvallen op standaard thema... Theme ingesteld op {0}. diff --git a/ModAssistant/Localisation/ru.xaml b/ModAssistant/Localisation/ru.xaml index 007e6b8..264bc1e 100644 --- a/ModAssistant/Localisation/ru.xaml +++ b/ModAssistant/Localisation/ru.xaml @@ -151,6 +151,10 @@ Установка плейлиста: {0} Ошибка с песней: {0} [{0} ошибок] Установка плейлиста окончена: {1} + Show OneClick Installer Window + Yes + Close + No Диагностика Открыть логи Открыть AppData @@ -222,8 +226,9 @@ Установка: {0} Достигнуто максимальное кол-во попыток: Пропускаем {0} Достигнут лимит. Возобновление через {0} - Скачивание неудалось: {0} - + Скачивание неудалось: {0} + Done'd + Тема не найдена, возвращаемся к стандартной теме... Установлена тема: {0}. diff --git a/ModAssistant/Localisation/sv.xaml b/ModAssistant/Localisation/sv.xaml index 9b3919d..30fc6ee 100644 --- a/ModAssistant/Localisation/sv.xaml +++ b/ModAssistant/Localisation/sv.xaml @@ -103,6 +103,7 @@ Detta kan leda till att dina andra mods slutar att fungera Extrahering misslyckades {0}, försöker igen om {1} sekunder. ({2}/{3}) Misslyckades med att extrahera {0} efter maxantalet försök ({1}), hoppar över. Denna mod kanske inte fungerar som den ska så fortsätt på egen risk. + Search... Om @@ -140,9 +141,20 @@ Aktivera OneClick™-Installationer BeatSaver ModelSaber + Playlists + Close window when finished Spelvariant Steam Oculus + Tools + Install Playlist + Installing Playlist: {0} + Failed song: {0} + [{0} fails] Finished Installing Playlist: {1} + Show OneClick Installer Window + Yes + Close + No Diagnostikverktyg Öppna Loggar Öppna AppData @@ -211,6 +223,11 @@ Misslyckades med att installera. {0} OneClick™-installeringshanterare registrerade! {0} OneClick™-installeringshanterare avregistrerade! + Installing: {0} + Max tries reached: Skipping {0} + Ratelimit hit. Resuming in {0} + Download failed: {0} + Done'd Temat hittades inte, återställer till standardtemat... diff --git a/tools/README.md b/tools/README.md new file mode 100644 index 0000000..3d7e0ac --- /dev/null +++ b/tools/README.md @@ -0,0 +1,7 @@ +# ModAssistant Tools +> These are tools used to build / improve ModAssistant. **They are not to be distributed with the compiled binary.** + +## Translation Stubs +Use `generate_translation_stubs.py` to read the English locale file and generate missing strings for all other locales. Requires Python 3.6 or above. + +Simply run `python ./tools/generate_translation_stubs.py` and commit the stubs. diff --git a/tools/generate_translation_stubs.py b/tools/generate_translation_stubs.py new file mode 100644 index 0000000..7aced83 --- /dev/null +++ b/tools/generate_translation_stubs.py @@ -0,0 +1,144 @@ +# -*- coding: utf-8 -*- +import os +import re +from shutil import copyfile + +# --------------- Configuration ---------------- # +master_file = "./ModAssistant/Localisation/en.xaml" +source_dir = "./ModAssistant/Localisation" +target_dir = source_dir +comment = " " +# --------------- Configuration ---------------- # + + +def read_file(filepath): + """ + Read file content + :param filepath: + :return: + """ + with open(filepath, "r", encoding="utf-8") as file: + data = file.read() + return data + + +def find_files(root_directory): + """ + Find all files to be processed + :param root_directory: + :return: + """ + for root, ds, fs in os.walk(root_directory): + for fn in fs: + fullname = os.path.join(root, fn) + master_name = os.path.basename(master_file) + if master_name in fullname: + continue + yield fullname + + +def search(regex, m_string, group=1): + """ + Search for the first item that matches by regular expression + :param regex: + :param m_string: + :return: + """ + found = re.compile(regex, re.M).search(m_string) + result = "" + if found: + result = found.group(group) + return result + + +def write_file(filepath, content): + """ + Write text content to file + :param filepath: + :param content: + :return: + """ + if not os.path.exists(target_dir): + os.makedirs(target_dir, exist_ok=True) + with open(filepath, "w", encoding="utf-8") as f: + f.write(content) + + +def find_items(data): + keys_regex = r"<\s*([^\s>]+)\s.*Key[^>]+>" + keys_matches = re.finditer(keys_regex, data, re.M) + items = [] + for n, m in enumerate(keys_matches, start=1): + if len(items): + last_dict = items[-1] + if len(last_dict): + last_dict['end'] = m.start() + items.append({"match": m[0], "name": m[1], "start": m.end()}) + items[-1]['end'] = len(data) + for item in items: + item_text = data[item['start']: item['end']] + end_tag = "" % item['name'] + full_tag = item['match'] + item_text[:item_text.rfind(end_tag) + len(end_tag)] + item['end_tag'] = end_tag + item['full_tag'] = full_tag + return items + + +def wrapper_key(match, content): + """ + Try to find the comment behind the key + :param match: + :param content: + :return: + """ + regex = "(\s*" + re.escape(match) + "(\ *<\!\-\-[^\-]+\-\->)?\s*)" + with_comment = search(r"" + str(regex), content, 1) + # print(regex) + # print(match) + # print(with_comment) + # print("-----") + if with_comment: + match = with_comment + return match + + +def main(): + """ + Cycle processing of xaml files except master_file + :return: + """ + master_data = read_file(master_file) + print("The master file is", master_file) + items = find_items(master_data) + + for f in find_files(source_dir): + content = master_data + "" + xml_data = read_file(f) + xml_dict = {} + for xml_item in find_items(xml_data): + xml_dict[xml_item['match']] = xml_item['full_tag'] + for item in items: + # print(f) + # if "OneClick:Done" in item['match'] and "fr.xaml" in f: + # print("----") + # pass + if item['match'] in xml_dict.keys(): + match = wrapper_key(xml_dict[item['match']], xml_data) + master_match = wrapper_key(item['full_tag'], content) + # print(master_match) + content = content.replace(master_match, match) + else: + pre_blanks = search(r"(\s*)" + re.escape(item['full_tag']), master_data) + content = re.sub(r"\s*" + re.escape(item['full_tag']), pre_blanks + item['full_tag'] + comment, content) + # Put the processed files in the "dist" directory + filepath = f.replace(source_dir, target_dir) + write_file(filepath, content) + print("Processing", f) + # Copy "master_file" to the target directory + if source_dir != target_dir: + copyfile(master_file, master_file.replace(source_dir, target_dir)) + + +if __name__ == '__main__': + main() + print("done'd!")