From cb18b3881f15785c194776ee670d2f896bcf4295 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 27 Nov 2020 19:42:45 +0100 Subject: [PATCH 01/21] Fix Debian package version --- debian/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 887634f..2399e41 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -python3-squirrel-battle (3.14) beta; urgency=low +python3-squirrel-battle (3.14.1) beta; urgency=low * Some graphical improvements. From e3be4b4f3f62689202a627035b853be294196e3d Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 27 Nov 2020 20:32:40 +0100 Subject: [PATCH 02/21] First setup for translation --- locale/en/LC_MESSAGES/squirrelbattle.mo | Bin 0 -> 371 bytes locale/en/LC_MESSAGES/squirrelbattle.po | 22 ++++++++++++++++++++++ locale/fr/LC_MESSAGES/squirrelbattle.mo | Bin 0 -> 371 bytes locale/fr/LC_MESSAGES/squirrelbattle.po | 22 ++++++++++++++++++++++ squirrelbattle/translations.py | 15 +++++++++++++++ 5 files changed, 59 insertions(+) create mode 100644 locale/en/LC_MESSAGES/squirrelbattle.mo create mode 100644 locale/en/LC_MESSAGES/squirrelbattle.po create mode 100644 locale/fr/LC_MESSAGES/squirrelbattle.mo create mode 100644 locale/fr/LC_MESSAGES/squirrelbattle.po create mode 100644 squirrelbattle/translations.py diff --git a/locale/en/LC_MESSAGES/squirrelbattle.mo b/locale/en/LC_MESSAGES/squirrelbattle.mo new file mode 100644 index 0000000000000000000000000000000000000000..ecca9e27bf3bf4b3c848e637f5bb9cf11bef0958 GIT binary patch literal 371 zcmYL@u};G<5QYOPOGXwJ2JdhMw#pP#)3_zVPC}Yig3Yuh7!|v+T?7xp>+vjH5Td{C zlYG*D^7nn%`${nT$T4z?93VraONI21d*o;@Nfv**#W&7xy4(LWF1n=h?o}@%)oN(8dZR?JVmj|k zhC+!5+mCEsaZ^v~0=vr$|8?sJ1aQGdj<%~~0INtQ3l2OY2G%>)L!UZ?e} VJ#f2pD`Q(q22UoYNuxtdegF@5)Y literal 0 HcmV?d00001 diff --git a/locale/en/LC_MESSAGES/squirrelbattle.po b/locale/en/LC_MESSAGES/squirrelbattle.po new file mode 100644 index 0000000..85d099d --- /dev/null +++ b/locale/en/LC_MESSAGES/squirrelbattle.po @@ -0,0 +1,22 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-11-27 20:06+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: squirrelbattle/translations.py:7 +msgid "Toto" +msgstr "Test" diff --git a/locale/fr/LC_MESSAGES/squirrelbattle.mo b/locale/fr/LC_MESSAGES/squirrelbattle.mo new file mode 100644 index 0000000000000000000000000000000000000000..ecca9e27bf3bf4b3c848e637f5bb9cf11bef0958 GIT binary patch literal 371 zcmYL@u};G<5QYOPOGXwJ2JdhMw#pP#)3_zVPC}Yig3Yuh7!|v+T?7xp>+vjH5Td{C zlYG*D^7nn%`${nT$T4z?93VraONI21d*o;@Nfv**#W&7xy4(LWF1n=h?o}@%)oN(8dZR?JVmj|k zhC+!5+mCEsaZ^v~0=vr$|8?sJ1aQGdj<%~~0INtQ3l2OY2G%>)L!UZ?e} VJ#f2pD`Q(q22UoYNuxtdegF@5)Y literal 0 HcmV?d00001 diff --git a/locale/fr/LC_MESSAGES/squirrelbattle.po b/locale/fr/LC_MESSAGES/squirrelbattle.po new file mode 100644 index 0000000..85d099d --- /dev/null +++ b/locale/fr/LC_MESSAGES/squirrelbattle.po @@ -0,0 +1,22 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-11-27 20:06+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: squirrelbattle/translations.py:7 +msgid "Toto" +msgstr "Test" diff --git a/squirrelbattle/translations.py b/squirrelbattle/translations.py new file mode 100644 index 0000000..27ec288 --- /dev/null +++ b/squirrelbattle/translations.py @@ -0,0 +1,15 @@ +# Copyright (C) 2020 by ÿnérant, eichhornchen, nicomarg, charlse +# SPDX-License-Identifier: GPL-3.0-or-later + +import gettext + + +_TRANSLATORS = dict() +for language in ["en", "fr"]: + _TRANSLATORS[language] = gettext.translation("squirrelbattle", + localedir="locale", + languages=[language]) + + +def gettext(message: str) -> str: + return _TRANSLATORS.get("en", _TRANSLATORS.get("en")).gettext(message) From 2498fd2a61517aa562fdcab9e66359212cb7834c Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 27 Nov 2020 20:42:19 +0100 Subject: [PATCH 03/21] Translate strings --- locale/en/LC_MESSAGES/squirrelbattle.mo | Bin 371 -> 337 bytes locale/en/LC_MESSAGES/squirrelbattle.po | 68 ++++++++++++++++++++-- locale/fr/LC_MESSAGES/squirrelbattle.mo | Bin 371 -> 1445 bytes locale/fr/LC_MESSAGES/squirrelbattle.po | 74 ++++++++++++++++++++++-- squirrelbattle/display/statsdisplay.py | 8 +-- squirrelbattle/game.py | 15 +++-- squirrelbattle/interfaces.py | 12 ++-- squirrelbattle/menus.py | 15 ++--- 8 files changed, 163 insertions(+), 29 deletions(-) diff --git a/locale/en/LC_MESSAGES/squirrelbattle.mo b/locale/en/LC_MESSAGES/squirrelbattle.mo index ecca9e27bf3bf4b3c848e637f5bb9cf11bef0958..6c5906d1cd061dff54de8b533942893de34efc9e 100644 GIT binary patch delta 65 wcmey&bdky8o)F7a1|VPrVi_P-0b*t#)&XJ=umEClprj>`2C0F8jiHi^0R0~YqyPW_ delta 100 zcmcb}^qDF2o)F7a1|VPpVi_RT0b*7lwgF-g2moRhAPxj#aYhD)FepC{$Oa-X0O^H; Sko=PTjTVxOtRbnzB@6)iEeZ($ diff --git a/locale/en/LC_MESSAGES/squirrelbattle.po b/locale/en/LC_MESSAGES/squirrelbattle.po index 85d099d..31fcdec 100644 --- a/locale/en/LC_MESSAGES/squirrelbattle.po +++ b/locale/en/LC_MESSAGES/squirrelbattle.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-11-27 20:06+0100\n" +"POT-Creation-Date: 2020-11-27 20:39+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,6 +17,66 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: squirrelbattle/translations.py:7 -msgid "Toto" -msgstr "Test" +#: squirrelbattle/display/statsdisplay.py:34 +msgid "Inventory:" +msgstr "" + +#: squirrelbattle/display/statsdisplay.py:39 +msgid "YOU ARE DEAD" +msgstr "" + +#: squirrelbattle/interfaces.py:394 +#, python-brace-format +msgid "{name} hits {opponent}." +msgstr "" + +#: squirrelbattle/interfaces.py:405 +#, python-brace-format +msgid "{name} takes {amount} damage." +msgstr "" + +#: squirrelbattle/menus.py:45 +msgid "New game" +msgstr "" + +#: squirrelbattle/menus.py:46 +msgid "Resume" +msgstr "" + +#: squirrelbattle/menus.py:47 +msgid "Save" +msgstr "" + +#: squirrelbattle/menus.py:48 +msgid "Load" +msgstr "" + +#: squirrelbattle/menus.py:49 +msgid "Settings" +msgstr "" + +#: squirrelbattle/menus.py:50 +msgid "Exit" +msgstr "" + +#: squirrelbattle/menus.py:71 +msgid "Back" +msgstr "" + +#: squirrelbattle/game.py:147 +msgid "" +"Some keys are missing in your save file.\n" +"Your save seems to be corrupt. It got deleted." +msgstr "" + +#: squirrelbattle/game.py:155 +msgid "" +"No player was found on this map!\n" +"Maybe you died?" +msgstr "" + +#: squirrelbattle/game.py:175 +msgid "" +"The JSON file is not correct.\n" +"Your save seems corrupted.It got deleted." +msgstr "" diff --git a/locale/fr/LC_MESSAGES/squirrelbattle.mo b/locale/fr/LC_MESSAGES/squirrelbattle.mo index ecca9e27bf3bf4b3c848e637f5bb9cf11bef0958..7e3ecd63e13fc07cf7b1df1e42fa1bffd4ee8666 100644 GIT binary patch literal 1445 zcmbu8yRREX6vihIUgjmyAS94ZDiCOw&_yPYY_2yKhxG$LF1mDM@9}zay)(M1 z6m*CZL{Ek3DXC0DL4zm}eM{$+Ay;haj&w9Lwa&?C@^j^=l+~q1N3JGJD^pXh zIKL(a>}s4F$|WA`z0!pfLsK%H@XC?2Or>%T%cOKTXUV~rW@^E4ox{l8SA5tD^wocs0$a3Op_Y@UNqpP3TL90^xUN5G#NylUerqHonEuke(i%^ zH*I9n`DkRNb_BP><)k{&na;={IRQm)5a=YdpFcT{-s) zWzE<|sh*k~U$;qDCdxOU2aj(m-m8`OY z+tdto=$9pJ)_$`lZ{Y_ztS%%?;mmZY(dXJno9{eA;>j*rni}H7P17|I`cS$?lA%PB zLfRbfeQ9O6`4&f)`JW1A diff --git a/locale/fr/LC_MESSAGES/squirrelbattle.po b/locale/fr/LC_MESSAGES/squirrelbattle.po index 85d099d..ab04ec8 100644 --- a/locale/fr/LC_MESSAGES/squirrelbattle.po +++ b/locale/fr/LC_MESSAGES/squirrelbattle.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-11-27 20:06+0100\n" +"POT-Creation-Date: 2020-11-27 20:39+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,6 +17,72 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: squirrelbattle/translations.py:7 -msgid "Toto" -msgstr "Test" +#: squirrelbattle/display/statsdisplay.py:34 +msgid "Inventory:" +msgstr "Inventaire :" + +#: squirrelbattle/display/statsdisplay.py:39 +msgid "YOU ARE DEAD" +msgstr "VOUS ÊTES MORT" + +#: squirrelbattle/interfaces.py:394 +#, python-brace-format +msgid "{name} hits {opponent}." +msgstr "{name} frappe {opponent}." + +#: squirrelbattle/interfaces.py:405 +#, python-brace-format +msgid "{name} takes {amount} damage." +msgstr "{name} prend {amount} points de dégât." + +#: squirrelbattle/menus.py:45 +msgid "New game" +msgstr "Nouvelle partie" + +#: squirrelbattle/menus.py:46 +msgid "Resume" +msgstr "Continuer" + +#: squirrelbattle/menus.py:47 +msgid "Save" +msgstr "Sauvegarder" + +#: squirrelbattle/menus.py:48 +msgid "Load" +msgstr "Charger" + +#: squirrelbattle/menus.py:49 +msgid "Settings" +msgstr "Paramètres" + +#: squirrelbattle/menus.py:50 +msgid "Exit" +msgstr "Quitter" + +#: squirrelbattle/menus.py:71 +msgid "Back" +msgstr "Retour" + +#: squirrelbattle/game.py:147 +msgid "" +"Some keys are missing in your save file.\n" +"Your save seems to be corrupt. It got deleted." +msgstr "" +"Certaines clés de votre ficher de sauvegarde sont manquantes.\n" +"Votre sauvegarde semble corrompue. Elle a été supprimée." + +#: squirrelbattle/game.py:155 +msgid "" +"No player was found on this map!\n" +"Maybe you died?" +msgstr "" +"Aucun joueur n'a été trouvé sur la carte !\n" +"Peut-être êtes-vous mort ?" + +#: squirrelbattle/game.py:175 +msgid "" +"The JSON file is not correct.\n" +"Your save seems corrupted.It got deleted." +msgstr "" +"Le fichier JSON de sauvegarde est incorrect.\n" +"Votre sauvegarde semble corrompue. Elle a été supprimée." diff --git a/squirrelbattle/display/statsdisplay.py b/squirrelbattle/display/statsdisplay.py index b65e716..da9213f 100644 --- a/squirrelbattle/display/statsdisplay.py +++ b/squirrelbattle/display/statsdisplay.py @@ -3,10 +3,10 @@ import curses +from ..entities.player import Player +from ..translations import gettext as _ from .display import Display -from squirrelbattle.entities.player import Player - class StatsDisplay(Display): player: Player @@ -31,12 +31,12 @@ class StatsDisplay(Display): self.player.dexterity, self.player.constitution) self.addstr(self.pad, 3, 0, string3) - inventory_str = "Inventaire : " + "".join( + inventory_str = _("Inventory:") + " " + "".join( self.pack[item.name.upper()] for item in self.player.inventory) self.addstr(self.pad, 8, 0, inventory_str) if self.player.dead: - self.addstr(self.pad, 10, 0, "VOUS ÊTES MORT", + self.addstr(self.pad, 10, 0, _("YOU ARE DEAD"), curses.A_BOLD | curses.A_BLINK | curses.A_STANDOUT | self.color_pair(3)) diff --git a/squirrelbattle/game.py b/squirrelbattle/game.py index a64d82e..a9689a5 100644 --- a/squirrelbattle/game.py +++ b/squirrelbattle/game.py @@ -1,5 +1,6 @@ # Copyright (C) 2020 by ÿnérant, eichhornchen, nicomarg, charlse # SPDX-License-Identifier: GPL-3.0-or-later + from json import JSONDecodeError from random import randint from typing import Any, Optional @@ -13,6 +14,7 @@ from .interfaces import Map, Logs from .resources import ResourceManager from .settings import Settings from . import menus +from .translations import gettext as _ from typing import Callable @@ -142,16 +144,16 @@ class Game: try: self.map.load_state(d) except KeyError: - self.message = "Some keys are missing in your save file.\n" \ - "Your save seems to be corrupt. It got deleted." + self.message = _("Some keys are missing in your save file.\n" + "Your save seems to be corrupt. It got deleted.") os.unlink(ResourceManager.get_config_path("save.json")) self.display_actions(DisplayActions.UPDATE) return players = self.map.find_entities(Player) if not players: - self.message = "No player was found on this map!\n" \ - "Maybe you died?" + self.message = _("No player was found on this map!\n" + "Maybe you died?") self.player.health = 0 self.display_actions(DisplayActions.UPDATE) return @@ -170,8 +172,9 @@ class Game: state = json.loads(f.read()) self.load_state(state) except JSONDecodeError: - self.message = "The JSON file is not correct.\n" \ - "Your save seems corrupted. It got deleted." + self.message = _("The JSON file is not correct.\n" + "Your save seems corrupted." + "It got deleted.") os.unlink(file_path) self.display_actions(DisplayActions.UPDATE) diff --git a/squirrelbattle/interfaces.py b/squirrelbattle/interfaces.py index 8958e7b..0e51589 100644 --- a/squirrelbattle/interfaces.py +++ b/squirrelbattle/interfaces.py @@ -6,7 +6,8 @@ from math import sqrt from random import choice, randint from typing import List, Optional -from squirrelbattle.display.texturepack import TexturePack +from .display.texturepack import TexturePack +from .translations import gettext as _ class Logs: @@ -390,7 +391,8 @@ class FightingEntity(Entity): """ Deals damage to the opponent, based on the stats """ - return f"{self.name} hits {opponent.name}. "\ + return _("{name} hits {opponent}.")\ + .format(name=str(self), opponent=str(opponent)) + " "\ + opponent.take_damage(self, self.strength) def take_damage(self, attacker: "Entity", amount: int) -> str: @@ -400,8 +402,10 @@ class FightingEntity(Entity): self.health -= amount if self.health <= 0: self.die() - return f"{self.name} takes {amount} damage."\ - + (f" {self.name} dies." if self.health <= 0 else "") + return _("{name} takes {amount} damage.")\ + .format(name=str(self), amount=str(amount)) \ + + (" " + "{name} dies.".format(name=str(self)) + if self.health <= 0 else "") def die(self) -> None: """ diff --git a/squirrelbattle/menus.py b/squirrelbattle/menus.py index 31c50ea..3c2d9e8 100644 --- a/squirrelbattle/menus.py +++ b/squirrelbattle/menus.py @@ -7,6 +7,7 @@ from typing import Any, Optional from .display.texturepack import TexturePack from .enums import GameMode, KeyValues, DisplayActions from .settings import Settings +from .translations import gettext as _ class Menu: @@ -41,12 +42,12 @@ class MainMenuValues(Enum): """ Values of the main menu """ - START = 'Nouvelle partie' - RESUME = 'Continuer' - SAVE = 'Sauvegarder' - LOAD = 'Charger' - SETTINGS = 'Paramètres' - EXIT = 'Quitter' + START = _("New game") + RESUME = _("Resume") + SAVE = _("Save") + LOAD = _("Load") + SETTINGS = _("Settings") + EXIT = _("Exit") def __str__(self): return self.value @@ -67,7 +68,7 @@ class SettingsMenu(Menu): def update_values(self, settings: Settings) -> None: self.values = list(settings.__dict__.items()) - self.values.append(("RETURN", ["", "Retour"])) + self.values.append(("RETURN", ["", _("Back")])) def handle_key_pressed(self, key: Optional[KeyValues], raw_key: str, game: Any) -> None: From 4287b4f045f91139b0c4d9c45965d2cab0adba60 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 27 Nov 2020 20:53:24 +0100 Subject: [PATCH 04/21] Add possibility to change the language --- squirrelbattle/game.py | 3 ++- squirrelbattle/interfaces.py | 8 ++++---- squirrelbattle/menus.py | 8 +++++++- squirrelbattle/settings.py | 2 ++ squirrelbattle/translations.py | 17 +++++++++++++++-- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/squirrelbattle/game.py b/squirrelbattle/game.py index a9689a5..be1e01a 100644 --- a/squirrelbattle/game.py +++ b/squirrelbattle/game.py @@ -14,7 +14,7 @@ from .interfaces import Map, Logs from .resources import ResourceManager from .settings import Settings from . import menus -from .translations import gettext as _ +from .translations import gettext as _, setlocale from typing import Callable @@ -38,6 +38,7 @@ class Game: self.settings.load_settings() self.settings.write_settings() self.settings_menu.update_values(self.settings) + setlocale(self.settings.LOCALE) self.logs = Logs() self.message = None diff --git a/squirrelbattle/interfaces.py b/squirrelbattle/interfaces.py index 0e51589..845e3bd 100644 --- a/squirrelbattle/interfaces.py +++ b/squirrelbattle/interfaces.py @@ -129,7 +129,7 @@ class Map: """ Put randomly {count} hedgehogs on the map, where it is available. """ - for _ in range(count): + for ignored in range(count): y, x = 0, 0 while True: y, x = randint(0, self.height - 1), randint(0, self.width - 1) @@ -392,7 +392,7 @@ class FightingEntity(Entity): Deals damage to the opponent, based on the stats """ return _("{name} hits {opponent}.")\ - .format(name=str(self), opponent=str(opponent)) + " "\ + .format(name=self.name, opponent=opponent.name) + " "\ + opponent.take_damage(self, self.strength) def take_damage(self, attacker: "Entity", amount: int) -> str: @@ -403,8 +403,8 @@ class FightingEntity(Entity): if self.health <= 0: self.die() return _("{name} takes {amount} damage.")\ - .format(name=str(self), amount=str(amount)) \ - + (" " + "{name} dies.".format(name=str(self)) + .format(name=self.name, amount=str(amount)) \ + + (" " + "{name} dies.".format(name=self.name) if self.health <= 0 else "") def die(self) -> None: diff --git a/squirrelbattle/menus.py b/squirrelbattle/menus.py index 3c2d9e8..56a7db2 100644 --- a/squirrelbattle/menus.py +++ b/squirrelbattle/menus.py @@ -7,7 +7,7 @@ from typing import Any, Optional from .display.texturepack import TexturePack from .enums import GameMode, KeyValues, DisplayActions from .settings import Settings -from .translations import gettext as _ +from .translations import gettext as _, setlocale class Menu: @@ -96,6 +96,12 @@ class SettingsMenu(Menu): game.settings.TEXTURE_PACK) game.settings.write_settings() self.update_values(game.settings) + elif option == "LOCALE": + game.settings.LOCALE = 'fr' if game.settings.LOCALE == 'en'\ + else 'en' + setlocale(game.settings.LOCALE) + game.settings.write_settings() + self.update_values(game.settings) else: self.waiting_for_key = True self.update_values(game.settings) diff --git a/squirrelbattle/settings.py b/squirrelbattle/settings.py index 9601457..726d96c 100644 --- a/squirrelbattle/settings.py +++ b/squirrelbattle/settings.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later import json +import locale import os from typing import Any, Generator @@ -35,6 +36,7 @@ class Settings: self.KEY_ENTER = \ ['\n', 'Touche pour valider un menu'] self.TEXTURE_PACK = ['ascii', 'Pack de textures utilisé'] + self.LOCALE = [locale.getlocale()[0][:2], 'Langue'] def __getattribute__(self, item: str) -> Any: superattribute = super().__getattribute__(item) diff --git a/squirrelbattle/translations.py b/squirrelbattle/translations.py index 27ec288..fa8196d 100644 --- a/squirrelbattle/translations.py +++ b/squirrelbattle/translations.py @@ -4,12 +4,25 @@ import gettext +SUPPORTED_LOCALES = ["en", "fr"] +DEFAULT_LOCALE = "en" + +_current_locale = DEFAULT_LOCALE + _TRANSLATORS = dict() -for language in ["en", "fr"]: +for language in SUPPORTED_LOCALES: _TRANSLATORS[language] = gettext.translation("squirrelbattle", localedir="locale", languages=[language]) def gettext(message: str) -> str: - return _TRANSLATORS.get("en", _TRANSLATORS.get("en")).gettext(message) + return _TRANSLATORS.get(_current_locale, + _TRANSLATORS.get("en")).gettext(message) + + +def setlocale(lang: str) -> None: + global _current_locale + lang = lang[:2] + if lang in SUPPORTED_LOCALES: + _current_locale = lang From c151e0f65620d4e0854b6b5bc7eb59b83fc7eb8e Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 27 Nov 2020 21:44:17 +0100 Subject: [PATCH 05/21] Menu items are translated --- locale/en/LC_MESSAGES/squirrelbattle.po | 20 ++++++++++---------- locale/fr/LC_MESSAGES/squirrelbattle.po | 20 ++++++++++---------- squirrelbattle/display/menudisplay.py | 2 +- squirrelbattle/menus.py | 14 +++++++------- squirrelbattle/tests/translations_test.py | 19 +++++++++++++++++++ 5 files changed, 47 insertions(+), 28 deletions(-) create mode 100644 squirrelbattle/tests/translations_test.py diff --git a/locale/en/LC_MESSAGES/squirrelbattle.po b/locale/en/LC_MESSAGES/squirrelbattle.po index 31fcdec..fb84fe2 100644 --- a/locale/en/LC_MESSAGES/squirrelbattle.po +++ b/locale/en/LC_MESSAGES/squirrelbattle.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-11-27 20:39+0100\n" +"POT-Creation-Date: 2020-11-27 21:43+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -35,27 +35,27 @@ msgstr "" msgid "{name} takes {amount} damage." msgstr "" -#: squirrelbattle/menus.py:45 +#: squirrelbattle/menus.py:45 squirrelbattle/tests/translations_test.py:14 msgid "New game" msgstr "" -#: squirrelbattle/menus.py:46 +#: squirrelbattle/menus.py:46 squirrelbattle/tests/translations_test.py:15 msgid "Resume" msgstr "" -#: squirrelbattle/menus.py:47 +#: squirrelbattle/menus.py:47 squirrelbattle/tests/translations_test.py:17 msgid "Save" msgstr "" -#: squirrelbattle/menus.py:48 +#: squirrelbattle/menus.py:48 squirrelbattle/tests/translations_test.py:16 msgid "Load" msgstr "" -#: squirrelbattle/menus.py:49 +#: squirrelbattle/menus.py:49 squirrelbattle/tests/translations_test.py:18 msgid "Settings" msgstr "" -#: squirrelbattle/menus.py:50 +#: squirrelbattle/menus.py:50 squirrelbattle/tests/translations_test.py:19 msgid "Exit" msgstr "" @@ -63,19 +63,19 @@ msgstr "" msgid "Back" msgstr "" -#: squirrelbattle/game.py:147 +#: squirrelbattle/game.py:147 squirrelbattle/game.py:148 msgid "" "Some keys are missing in your save file.\n" "Your save seems to be corrupt. It got deleted." msgstr "" -#: squirrelbattle/game.py:155 +#: squirrelbattle/game.py:155 squirrelbattle/game.py:156 msgid "" "No player was found on this map!\n" "Maybe you died?" msgstr "" -#: squirrelbattle/game.py:175 +#: squirrelbattle/game.py:175 squirrelbattle/game.py:176 msgid "" "The JSON file is not correct.\n" "Your save seems corrupted.It got deleted." diff --git a/locale/fr/LC_MESSAGES/squirrelbattle.po b/locale/fr/LC_MESSAGES/squirrelbattle.po index ab04ec8..0068f30 100644 --- a/locale/fr/LC_MESSAGES/squirrelbattle.po +++ b/locale/fr/LC_MESSAGES/squirrelbattle.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-11-27 20:39+0100\n" +"POT-Creation-Date: 2020-11-27 21:43+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -35,27 +35,27 @@ msgstr "{name} frappe {opponent}." msgid "{name} takes {amount} damage." msgstr "{name} prend {amount} points de dégât." -#: squirrelbattle/menus.py:45 +#: squirrelbattle/menus.py:45 squirrelbattle/tests/translations_test.py:14 msgid "New game" msgstr "Nouvelle partie" -#: squirrelbattle/menus.py:46 +#: squirrelbattle/menus.py:46 squirrelbattle/tests/translations_test.py:15 msgid "Resume" msgstr "Continuer" -#: squirrelbattle/menus.py:47 +#: squirrelbattle/menus.py:47 squirrelbattle/tests/translations_test.py:17 msgid "Save" msgstr "Sauvegarder" -#: squirrelbattle/menus.py:48 +#: squirrelbattle/menus.py:48 squirrelbattle/tests/translations_test.py:16 msgid "Load" msgstr "Charger" -#: squirrelbattle/menus.py:49 +#: squirrelbattle/menus.py:49 squirrelbattle/tests/translations_test.py:18 msgid "Settings" msgstr "Paramètres" -#: squirrelbattle/menus.py:50 +#: squirrelbattle/menus.py:50 squirrelbattle/tests/translations_test.py:19 msgid "Exit" msgstr "Quitter" @@ -63,7 +63,7 @@ msgstr "Quitter" msgid "Back" msgstr "Retour" -#: squirrelbattle/game.py:147 +#: squirrelbattle/game.py:147 squirrelbattle/game.py:148 msgid "" "Some keys are missing in your save file.\n" "Your save seems to be corrupt. It got deleted." @@ -71,7 +71,7 @@ msgstr "" "Certaines clés de votre ficher de sauvegarde sont manquantes.\n" "Votre sauvegarde semble corrompue. Elle a été supprimée." -#: squirrelbattle/game.py:155 +#: squirrelbattle/game.py:155 squirrelbattle/game.py:156 msgid "" "No player was found on this map!\n" "Maybe you died?" @@ -79,7 +79,7 @@ msgstr "" "Aucun joueur n'a été trouvé sur la carte !\n" "Peut-être êtes-vous mort ?" -#: squirrelbattle/game.py:175 +#: squirrelbattle/game.py:175 squirrelbattle/game.py:176 msgid "" "The JSON file is not correct.\n" "Your save seems corrupted.It got deleted." diff --git a/squirrelbattle/display/menudisplay.py b/squirrelbattle/display/menudisplay.py index 731ecee..e388a83 100644 --- a/squirrelbattle/display/menudisplay.py +++ b/squirrelbattle/display/menudisplay.py @@ -18,7 +18,7 @@ class MenuDisplay(Display): def update_menu(self, menu: Menu) -> None: self.menu = menu self.trueheight = len(self.values) - self.truewidth = max([len(a) for a in self.values]) + self.truewidth = max([len(str(a)) for a in self.values]) # Menu values are printed in pad self.pad = self.newpad(self.trueheight, self.truewidth + 2) diff --git a/squirrelbattle/menus.py b/squirrelbattle/menus.py index 56a7db2..3f6f7a0 100644 --- a/squirrelbattle/menus.py +++ b/squirrelbattle/menus.py @@ -42,15 +42,15 @@ class MainMenuValues(Enum): """ Values of the main menu """ - START = _("New game") - RESUME = _("Resume") - SAVE = _("Save") - LOAD = _("Load") - SETTINGS = _("Settings") - EXIT = _("Exit") + START = "New game" + RESUME = "Resume" + SAVE = "Save" + LOAD = "Load" + SETTINGS = "Settings" + EXIT = "Exit" def __str__(self): - return self.value + return _(self.value) class MainMenu(Menu): diff --git a/squirrelbattle/tests/translations_test.py b/squirrelbattle/tests/translations_test.py new file mode 100644 index 0000000..de93eb4 --- /dev/null +++ b/squirrelbattle/tests/translations_test.py @@ -0,0 +1,19 @@ +import unittest + +from squirrelbattle.translations import gettext as _, setlocale + + +class TestTranslations(unittest.TestCase): + def setUp(self) -> None: + setlocale("fr") + + def test_translations(self): + """ + Ensure that some strings are well-translated. + """ + self.assertEqual(_("New game"), "Nouvelle partie") + self.assertEqual(_("Resume"), "Continuer") + self.assertEqual(_("Load"), "Charger") + self.assertEqual(_("Save"), "Sauvegarder") + self.assertEqual(_("Settings"), "Paramètres") + self.assertEqual(_("Exit"), "Quitter") From 31b7ece449ed66187a8cfb61d3d143d1956d56c5 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 27 Nov 2020 21:51:54 +0100 Subject: [PATCH 06/21] Main menu width must be updated when the language got changed --- squirrelbattle/display/menudisplay.py | 10 ++++++++-- squirrelbattle/game.py | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/squirrelbattle/display/menudisplay.py b/squirrelbattle/display/menudisplay.py index e388a83..e6bb00d 100644 --- a/squirrelbattle/display/menudisplay.py +++ b/squirrelbattle/display/menudisplay.py @@ -17,8 +17,6 @@ class MenuDisplay(Display): def update_menu(self, menu: Menu) -> None: self.menu = menu - self.trueheight = len(self.values) - self.truewidth = max([len(str(a)) for a in self.values]) # Menu values are printed in pad self.pad = self.newpad(self.trueheight, self.truewidth + 2) @@ -44,6 +42,14 @@ class MenuDisplay(Display): self.height - 2 + self.y, self.width - 2 + self.x) + @property + def truewidth(self) -> int: + return max([len(str(a)) for a in self.values]) + + @property + def trueheight(self) -> int: + return len(self.values) + @property def preferred_width(self) -> int: return self.truewidth + 6 diff --git a/squirrelbattle/game.py b/squirrelbattle/game.py index be1e01a..ad2f1cc 100644 --- a/squirrelbattle/game.py +++ b/squirrelbattle/game.py @@ -37,8 +37,8 @@ class Game: self.settings = Settings() self.settings.load_settings() self.settings.write_settings() - self.settings_menu.update_values(self.settings) setlocale(self.settings.LOCALE) + self.settings_menu.update_values(self.settings) self.logs = Logs() self.message = None From f07324662a594ac9b7a2a765147e55e090908b8e Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 27 Nov 2020 21:56:25 +0100 Subject: [PATCH 07/21] Cover the language change --- squirrelbattle/tests/game_test.py | 15 +++++++++++---- squirrelbattle/tests/translations_test.py | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/squirrelbattle/tests/game_test.py b/squirrelbattle/tests/game_test.py index 5081912..8f5b1c1 100644 --- a/squirrelbattle/tests/game_test.py +++ b/squirrelbattle/tests/game_test.py @@ -15,6 +15,7 @@ from squirrelbattle.entities.player import Player from squirrelbattle.game import Game, KeyValues, GameMode from squirrelbattle.menus import MainMenuValues from squirrelbattle.settings import Settings +from squirrelbattle.translations import gettext as _ class TestGame(unittest.TestCase): @@ -275,12 +276,18 @@ class TestGame(unittest.TestCase): self.game.handle_key_pressed(KeyValues.ENTER) self.assertEqual(self.game.settings.TEXTURE_PACK, "ascii") + # Change language + self.game.settings.LOCALE = "en" + self.game.handle_key_pressed(KeyValues.DOWN) + self.game.handle_key_pressed(KeyValues.ENTER) + self.assertEqual(self.game.settings.LOCALE, "fr") + self.assertEqual(_("New game"), "Nouvelle partie") + self.game.handle_key_pressed(KeyValues.ENTER) + self.assertEqual(self.game.settings.LOCALE, "en") + self.assertEqual(_("New game"), "New game") + # Navigate to "back" button self.game.handle_key_pressed(KeyValues.DOWN) - self.game.handle_key_pressed(KeyValues.DOWN) - self.game.handle_key_pressed(KeyValues.DOWN) - self.game.handle_key_pressed(KeyValues.DOWN) - self.game.handle_key_pressed(KeyValues.DOWN) self.game.handle_key_pressed(KeyValues.ENTER) self.assertEqual(self.game.state, GameMode.MAINMENU) diff --git a/squirrelbattle/tests/translations_test.py b/squirrelbattle/tests/translations_test.py index de93eb4..e51cb8a 100644 --- a/squirrelbattle/tests/translations_test.py +++ b/squirrelbattle/tests/translations_test.py @@ -7,7 +7,7 @@ class TestTranslations(unittest.TestCase): def setUp(self) -> None: setlocale("fr") - def test_translations(self): + def test_translations(self) -> None: """ Ensure that some strings are well-translated. """ From d2d74c97a4d5fe26145d4aaf7b1e84d9fecdd30c Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 27 Nov 2020 22:19:41 +0100 Subject: [PATCH 08/21] Settings menu was not translated --- locale/en/LC_MESSAGES/squirrelbattle.po | 47 +++++++++++++++++++++- locale/fr/LC_MESSAGES/squirrelbattle.mo | Bin 1445 -> 2310 bytes locale/fr/LC_MESSAGES/squirrelbattle.po | 47 +++++++++++++++++++++- squirrelbattle/display/menudisplay.py | 6 ++- squirrelbattle/game.py | 4 +- squirrelbattle/settings.py | 36 +++++++---------- squirrelbattle/tests/settings_test.py | 2 +- squirrelbattle/tests/translations_test.py | 21 ++++++++++ 8 files changed, 134 insertions(+), 29 deletions(-) diff --git a/locale/en/LC_MESSAGES/squirrelbattle.po b/locale/en/LC_MESSAGES/squirrelbattle.po index fb84fe2..9ca5419 100644 --- a/locale/en/LC_MESSAGES/squirrelbattle.po +++ b/locale/en/LC_MESSAGES/squirrelbattle.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-11-27 21:43+0100\n" +"POT-Creation-Date: 2020-11-27 22:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -36,6 +36,7 @@ msgid "{name} takes {amount} damage." msgstr "" #: squirrelbattle/menus.py:45 squirrelbattle/tests/translations_test.py:14 +#: squirrelbattle/tests/game_test.py:284 squirrelbattle/tests/game_test.py:287 msgid "New game" msgstr "" @@ -80,3 +81,47 @@ msgid "" "The JSON file is not correct.\n" "Your save seems corrupted.It got deleted." msgstr "" + +#: squirrelbattle/settings.py:21 squirrelbattle/tests/translations_test.py:21 +msgid "Main key to move up" +msgstr "" + +#: squirrelbattle/settings.py:22 squirrelbattle/tests/translations_test.py:23 +msgid "Secondary key to move up" +msgstr "" + +#: squirrelbattle/settings.py:23 squirrelbattle/tests/translations_test.py:25 +msgid "Main key to move down" +msgstr "" + +#: squirrelbattle/settings.py:24 squirrelbattle/tests/translations_test.py:27 +msgid "Secondary key to move down" +msgstr "" + +#: squirrelbattle/settings.py:25 squirrelbattle/tests/translations_test.py:29 +msgid "Main key to move left" +msgstr "" + +#: squirrelbattle/settings.py:26 squirrelbattle/tests/translations_test.py:31 +msgid "Secondary key to move left" +msgstr "" + +#: squirrelbattle/settings.py:27 squirrelbattle/tests/translations_test.py:33 +msgid "Main key to move right" +msgstr "" + +#: squirrelbattle/settings.py:29 squirrelbattle/tests/translations_test.py:35 +msgid "Secondary key to move right" +msgstr "" + +#: squirrelbattle/settings.py:30 squirrelbattle/tests/translations_test.py:37 +msgid "Key to validate a menu" +msgstr "" + +#: squirrelbattle/settings.py:31 squirrelbattle/tests/translations_test.py:39 +msgid "Texture pack" +msgstr "" + +#: squirrelbattle/settings.py:32 squirrelbattle/tests/translations_test.py:40 +msgid "Language" +msgstr "" diff --git a/locale/fr/LC_MESSAGES/squirrelbattle.mo b/locale/fr/LC_MESSAGES/squirrelbattle.mo index 7e3ecd63e13fc07cf7b1df1e42fa1bffd4ee8666..bc9146e56582ef46663f44ca84d8b24c1f344325 100644 GIT binary patch literal 2310 zcmbu9%WoVt9LHTK6qa`>?;`ywgb1o;3AeHonr(I(w%td%y9o*)BxlFF>t@CtY|p0K zDp!Pn8-f!T5JCiQ^w0}JNPFim01j|07bI?6_G~hw48}LWli)Eddd`6_f-(3I_!)Q} z{2II${0qDf{0H>=k3gB(M&L#$JuCxSIJr7<4~L+jj9PiHD3t;h|e zrG%#^3UxkO6*STrMN&j(SWDOp``UbnkLYR@aWmR&;oeKRnR_oyY~6be2DgQCQuQrs z>qK~Umbej=NNX`o2og**WMLNdWGsq>mF=+=BC$TyaHOk^$x>IOs-wPk6p2_k5fxcS zTy_~wOns_413~B8%|?C{AruOteyixZ-6v1a#3{EQy3$;tax0`tSgx?E3IX4sfpnIx z>NM2~m9SCVns&=N!G_XHJGScz7`ax17egG!m+XqM{LlW#Q}VWGyY z3p$1?8*`LqiOwz6YSbv#LpmMS%hlRkxl(C`?e^;sofK!#5j-hTt=w2x@|K*g)#hSZ z)TX~90}JZadbnfu%f;EkyjBiw2c1z0dmMuP66#N?SE)PT#tQe^Qs-Q7YDdnS)e|NN zRaZwyb%{=`N>@M~IwY7~%%pR|Oz#z!$Y6Za=@*gUlLv2RP% zNY#}okEgqM9AnQA0VhnYa(fU#jw|IAA51nfTDk+t3L5at;i_gs0lQG5#!11-Sr<-S z(wTsp>IF{YO*h^oXCMb!%*LF$5EgWzuqZMYjK6gV5Wd0&L!IG@qi*O7^I4H9Lp<6X zO8VSHJF&5oTkb=fNAy2qv!CGYvDsht*4XSPJB`gEH#`}C1Me)G7sjEYgr#mg-n6*l zG}PYjopoRsgcQe z(_dCR9{zk^*LX}Ut4*{@sLkJ#TXhTT@N#XxEB{CHa&xIo;}1Jwo9fM0XX{bv8J?zM cujeK;0#E(+bCYVR@Gil=XuR1Uf9ZTyp*O-h1s`J1e~vl5HtSg(#9&X@FUd^n# zM2{&?v4sWfIQuxE9$|!g)aPzbM9MN0>2p(M;R)$$LmQrxoV88uA{UO>p^mjS)X+b0 y4Cb+aNQbx}`3@L|JZ diff --git a/locale/fr/LC_MESSAGES/squirrelbattle.po b/locale/fr/LC_MESSAGES/squirrelbattle.po index 0068f30..9dac712 100644 --- a/locale/fr/LC_MESSAGES/squirrelbattle.po +++ b/locale/fr/LC_MESSAGES/squirrelbattle.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-11-27 21:43+0100\n" +"POT-Creation-Date: 2020-11-27 22:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -36,6 +36,7 @@ msgid "{name} takes {amount} damage." msgstr "{name} prend {amount} points de dégât." #: squirrelbattle/menus.py:45 squirrelbattle/tests/translations_test.py:14 +#: squirrelbattle/tests/game_test.py:284 squirrelbattle/tests/game_test.py:287 msgid "New game" msgstr "Nouvelle partie" @@ -86,3 +87,47 @@ msgid "" msgstr "" "Le fichier JSON de sauvegarde est incorrect.\n" "Votre sauvegarde semble corrompue. Elle a été supprimée." + +#: squirrelbattle/settings.py:21 squirrelbattle/tests/translations_test.py:21 +msgid "Main key to move up" +msgstr "Touche principale pour aller vers le haut" + +#: squirrelbattle/settings.py:22 squirrelbattle/tests/translations_test.py:23 +msgid "Secondary key to move up" +msgstr "Touche secondaire pour aller vers le haut" + +#: squirrelbattle/settings.py:23 squirrelbattle/tests/translations_test.py:25 +msgid "Main key to move down" +msgstr "Touche principale pour aller vers le bas" + +#: squirrelbattle/settings.py:24 squirrelbattle/tests/translations_test.py:27 +msgid "Secondary key to move down" +msgstr "Touche secondaire pour aller vers le bas" + +#: squirrelbattle/settings.py:25 squirrelbattle/tests/translations_test.py:29 +msgid "Main key to move left" +msgstr "Touche principale pour aller vers la gauche" + +#: squirrelbattle/settings.py:26 squirrelbattle/tests/translations_test.py:31 +msgid "Secondary key to move left" +msgstr "Touche secondaire pour aller vers la gauche" + +#: squirrelbattle/settings.py:27 squirrelbattle/tests/translations_test.py:33 +msgid "Main key to move right" +msgstr "Touche principale pour aller vers la droite" + +#: squirrelbattle/settings.py:29 squirrelbattle/tests/translations_test.py:35 +msgid "Secondary key to move right" +msgstr "Touche secondaire pour aller vers la droite" + +#: squirrelbattle/settings.py:30 squirrelbattle/tests/translations_test.py:37 +msgid "Key to validate a menu" +msgstr "Touche pour valider un menu" + +#: squirrelbattle/settings.py:31 squirrelbattle/tests/translations_test.py:39 +msgid "Texture pack" +msgstr "Pack de textures" + +#: squirrelbattle/settings.py:32 squirrelbattle/tests/translations_test.py:40 +msgid "Language" +msgstr "Langue" diff --git a/squirrelbattle/display/menudisplay.py b/squirrelbattle/display/menudisplay.py index e6bb00d..b3036a0 100644 --- a/squirrelbattle/display/menudisplay.py +++ b/squirrelbattle/display/menudisplay.py @@ -6,6 +6,7 @@ from typing import List from squirrelbattle.menus import Menu, MainMenu from .display import Display, Box from ..resources import ResourceManager +from ..translations import gettext as _ class MenuDisplay(Display): @@ -66,9 +67,10 @@ class MenuDisplay(Display): class SettingsMenuDisplay(MenuDisplay): @property def values(self) -> List[str]: - return [a[1][1] + (" : " + return [_(a[1][1]) + (" : " + ("?" if self.menu.waiting_for_key - and a == self.menu.validate() else a[1][0]) + and a == self.menu.validate() else a[1][0] + .replace("\n", "\\n")) if a[1][0] else "") for a in self.menu.values] diff --git a/squirrelbattle/game.py b/squirrelbattle/game.py index ad2f1cc..7851aee 100644 --- a/squirrelbattle/game.py +++ b/squirrelbattle/game.py @@ -32,12 +32,12 @@ class Game: Init the game. """ self.state = GameMode.MAINMENU - self.main_menu = menus.MainMenu() - self.settings_menu = menus.SettingsMenu() self.settings = Settings() self.settings.load_settings() self.settings.write_settings() setlocale(self.settings.LOCALE) + self.main_menu = menus.MainMenu() + self.settings_menu = menus.SettingsMenu() self.settings_menu.update_values(self.settings) self.logs = Logs() self.message = None diff --git a/squirrelbattle/settings.py b/squirrelbattle/settings.py index 726d96c..3090679 100644 --- a/squirrelbattle/settings.py +++ b/squirrelbattle/settings.py @@ -7,6 +7,7 @@ import os from typing import Any, Generator from .resources import ResourceManager +from .translations import gettext as _ class Settings: @@ -17,26 +18,17 @@ class Settings: We can define the setting by simply use settings.TEXTURE_PACK = 'new_key' """ def __init__(self): - self.KEY_UP_PRIMARY = \ - ['z', 'Touche principale pour aller vers le haut'] - self.KEY_UP_SECONDARY = \ - ['KEY_UP', 'Touche secondaire pour aller vers le haut'] - self.KEY_DOWN_PRIMARY = \ - ['s', 'Touche principale pour aller vers le bas'] - self.KEY_DOWN_SECONDARY = \ - ['KEY_DOWN', 'Touche secondaire pour aller vers le bas'] - self.KEY_LEFT_PRIMARY = \ - ['q', 'Touche principale pour aller vers la gauche'] - self.KEY_LEFT_SECONDARY = \ - ['KEY_LEFT', 'Touche secondaire pour aller vers la gauche'] - self.KEY_RIGHT_PRIMARY = \ - ['d', 'Touche principale pour aller vers la droite'] - self.KEY_RIGHT_SECONDARY = \ - ['KEY_RIGHT', 'Touche secondaire pour aller vers la droite'] - self.KEY_ENTER = \ - ['\n', 'Touche pour valider un menu'] - self.TEXTURE_PACK = ['ascii', 'Pack de textures utilisé'] - self.LOCALE = [locale.getlocale()[0][:2], 'Langue'] + self.KEY_UP_PRIMARY = ['z', 'Main key to move up'] + self.KEY_UP_SECONDARY = ['KEY_UP', 'Secondary key to move up'] + self.KEY_DOWN_PRIMARY = ['s', 'Main key to move down'] + self.KEY_DOWN_SECONDARY = ['KEY_DOWN', 'Secondary key to move down'] + self.KEY_LEFT_PRIMARY = ['q', 'Main key to move left'] + self.KEY_LEFT_SECONDARY = ['KEY_LEFT', 'Secondary key to move left'] + self.KEY_RIGHT_PRIMARY = ['d', 'Main key to move right'] + self.KEY_RIGHT_SECONDARY = ['KEY_RIGHT', 'Secondary key to move right'] + self.KEY_ENTER = ['\n', 'Key to validate a menu'] + self.TEXTURE_PACK = ['ascii', 'Texture pack'] + self.LOCALE = [locale.getlocale()[0][:2], 'Language'] def __getattribute__(self, item: str) -> Any: superattribute = super().__getattribute__(item) @@ -55,10 +47,10 @@ class Settings: Retrieve the comment of a setting. """ if item in self.settings_keys: - return object.__getattribute__(self, item)[1] + return _(object.__getattribute__(self, item)[1]) for key in self.settings_keys: if getattr(self, key) == item: - return object.__getattribute__(self, key)[1] + return _(object.__getattribute__(self, key)[1]) @property def settings_keys(self) -> Generator[str, Any, None]: diff --git a/squirrelbattle/tests/settings_test.py b/squirrelbattle/tests/settings_test.py index cef60c0..b0d9739 100644 --- a/squirrelbattle/tests/settings_test.py +++ b/squirrelbattle/tests/settings_test.py @@ -24,7 +24,7 @@ class TestSettings(unittest.TestCase): self.assertEqual(settings.get_comment(settings.TEXTURE_PACK), settings.get_comment('TEXTURE_PACK')) self.assertEqual(settings.get_comment(settings.TEXTURE_PACK), - 'Pack de textures utilisé') + 'Texture pack') settings.TEXTURE_PACK = 'squirrel' self.assertEqual(settings.TEXTURE_PACK, 'squirrel') diff --git a/squirrelbattle/tests/translations_test.py b/squirrelbattle/tests/translations_test.py index e51cb8a..0d190d6 100644 --- a/squirrelbattle/tests/translations_test.py +++ b/squirrelbattle/tests/translations_test.py @@ -17,3 +17,24 @@ class TestTranslations(unittest.TestCase): self.assertEqual(_("Save"), "Sauvegarder") self.assertEqual(_("Settings"), "Paramètres") self.assertEqual(_("Exit"), "Quitter") + + self.assertEqual(_("Main key to move up"), + "Touche principale pour aller vers le haut") + self.assertEqual(_("Secondary key to move up"), + "Touche secondaire pour aller vers le haut") + self.assertEqual(_("Main key to move down"), + "Touche principale pour aller vers le bas") + self.assertEqual(_("Secondary key to move down"), + "Touche secondaire pour aller vers le bas") + self.assertEqual(_("Main key to move left"), + "Touche principale pour aller vers la gauche") + self.assertEqual(_("Secondary key to move left"), + "Touche secondaire pour aller vers la gauche") + self.assertEqual(_("Main key to move right"), + "Touche principale pour aller vers la droite") + self.assertEqual(_("Secondary key to move right"), + "Touche secondaire pour aller vers la droite") + self.assertEqual(_("Key to validate a menu"), + "Touche pour valider un menu") + self.assertEqual(_("Texture pack"), "Pack de textures") + self.assertEqual(_("Language"), "Langue") From 8f85093eb8b0796859be289ad23eb999c0591a25 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 27 Nov 2020 22:21:16 +0100 Subject: [PATCH 09/21] One string was missing --- locale/en/LC_MESSAGES/squirrelbattle.po | 9 +++++++-- locale/fr/LC_MESSAGES/squirrelbattle.po | 9 +++++++-- squirrelbattle/game.py | 2 +- squirrelbattle/interfaces.py | 2 +- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/locale/en/LC_MESSAGES/squirrelbattle.po b/locale/en/LC_MESSAGES/squirrelbattle.po index 9ca5419..a027782 100644 --- a/locale/en/LC_MESSAGES/squirrelbattle.po +++ b/locale/en/LC_MESSAGES/squirrelbattle.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-11-27 22:05+0100\n" +"POT-Creation-Date: 2020-11-27 22:20+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -79,7 +79,7 @@ msgstr "" #: squirrelbattle/game.py:175 squirrelbattle/game.py:176 msgid "" "The JSON file is not correct.\n" -"Your save seems corrupted.It got deleted." +"Your save seems corrupted. It got deleted." msgstr "" #: squirrelbattle/settings.py:21 squirrelbattle/tests/translations_test.py:21 @@ -125,3 +125,8 @@ msgstr "" #: squirrelbattle/settings.py:32 squirrelbattle/tests/translations_test.py:40 msgid "Language" msgstr "" + +#: squirrelbattle/interfaces.py:407 +#, python-brace-format +msgid "{name} dies." +msgstr "" diff --git a/locale/fr/LC_MESSAGES/squirrelbattle.po b/locale/fr/LC_MESSAGES/squirrelbattle.po index 9dac712..c47f2ca 100644 --- a/locale/fr/LC_MESSAGES/squirrelbattle.po +++ b/locale/fr/LC_MESSAGES/squirrelbattle.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-11-27 22:05+0100\n" +"POT-Creation-Date: 2020-11-27 22:20+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -83,7 +83,7 @@ msgstr "" #: squirrelbattle/game.py:175 squirrelbattle/game.py:176 msgid "" "The JSON file is not correct.\n" -"Your save seems corrupted.It got deleted." +"Your save seems corrupted. It got deleted." msgstr "" "Le fichier JSON de sauvegarde est incorrect.\n" "Votre sauvegarde semble corrompue. Elle a été supprimée." @@ -131,3 +131,8 @@ msgstr "Pack de textures" #: squirrelbattle/settings.py:32 squirrelbattle/tests/translations_test.py:40 msgid "Language" msgstr "Langue" + +#: squirrelbattle/interfaces.py:407 +#, python-brace-format +msgid "{name} dies." +msgstr "{name} meurt." diff --git a/squirrelbattle/game.py b/squirrelbattle/game.py index 7851aee..09f1328 100644 --- a/squirrelbattle/game.py +++ b/squirrelbattle/game.py @@ -174,7 +174,7 @@ class Game: self.load_state(state) except JSONDecodeError: self.message = _("The JSON file is not correct.\n" - "Your save seems corrupted." + "Your save seems corrupted. " "It got deleted.") os.unlink(file_path) self.display_actions(DisplayActions.UPDATE) diff --git a/squirrelbattle/interfaces.py b/squirrelbattle/interfaces.py index 845e3bd..78c1a15 100644 --- a/squirrelbattle/interfaces.py +++ b/squirrelbattle/interfaces.py @@ -404,7 +404,7 @@ class FightingEntity(Entity): self.die() return _("{name} takes {amount} damage.")\ .format(name=self.name, amount=str(amount)) \ - + (" " + "{name} dies.".format(name=self.name) + + (" " + _("{name} dies.").format(name=self.name) if self.health <= 0 else "") def die(self) -> None: From 70ae60b9a428c129355361aa6f71175155bd16bc Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 27 Nov 2020 22:33:58 +0100 Subject: [PATCH 10/21] Translate entities --- locale/en/LC_MESSAGES/squirrelbattle.po | 47 ++++++++++++++++++++-- locale/fr/LC_MESSAGES/squirrelbattle.mo | Bin 2310 -> 2607 bytes locale/fr/LC_MESSAGES/squirrelbattle.po | 47 ++++++++++++++++++++-- squirrelbattle/interfaces.py | 14 +++++-- squirrelbattle/tests/translations_test.py | 19 ++++++++- 5 files changed, 113 insertions(+), 14 deletions(-) diff --git a/locale/en/LC_MESSAGES/squirrelbattle.po b/locale/en/LC_MESSAGES/squirrelbattle.po index a027782..d77e823 100644 --- a/locale/en/LC_MESSAGES/squirrelbattle.po +++ b/locale/en/LC_MESSAGES/squirrelbattle.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-11-27 22:20+0100\n" +"POT-Creation-Date: 2020-11-27 22:31+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -25,12 +25,12 @@ msgstr "" msgid "YOU ARE DEAD" msgstr "" -#: squirrelbattle/interfaces.py:394 +#: squirrelbattle/interfaces.py:394 squirrelbattle/interfaces.py:398 #, python-brace-format msgid "{name} hits {opponent}." msgstr "" -#: squirrelbattle/interfaces.py:405 +#: squirrelbattle/interfaces.py:405 squirrelbattle/interfaces.py:410 #, python-brace-format msgid "{name} takes {amount} damage." msgstr "" @@ -83,50 +83,89 @@ msgid "" msgstr "" #: squirrelbattle/settings.py:21 squirrelbattle/tests/translations_test.py:21 +#: squirrelbattle/tests/translations_test.py:25 msgid "Main key to move up" msgstr "" #: squirrelbattle/settings.py:22 squirrelbattle/tests/translations_test.py:23 +#: squirrelbattle/tests/translations_test.py:27 msgid "Secondary key to move up" msgstr "" #: squirrelbattle/settings.py:23 squirrelbattle/tests/translations_test.py:25 +#: squirrelbattle/tests/translations_test.py:29 msgid "Main key to move down" msgstr "" #: squirrelbattle/settings.py:24 squirrelbattle/tests/translations_test.py:27 +#: squirrelbattle/tests/translations_test.py:31 msgid "Secondary key to move down" msgstr "" #: squirrelbattle/settings.py:25 squirrelbattle/tests/translations_test.py:29 +#: squirrelbattle/tests/translations_test.py:33 msgid "Main key to move left" msgstr "" #: squirrelbattle/settings.py:26 squirrelbattle/tests/translations_test.py:31 +#: squirrelbattle/tests/translations_test.py:35 msgid "Secondary key to move left" msgstr "" #: squirrelbattle/settings.py:27 squirrelbattle/tests/translations_test.py:33 +#: squirrelbattle/tests/translations_test.py:37 msgid "Main key to move right" msgstr "" #: squirrelbattle/settings.py:29 squirrelbattle/tests/translations_test.py:35 +#: squirrelbattle/tests/translations_test.py:39 msgid "Secondary key to move right" msgstr "" #: squirrelbattle/settings.py:30 squirrelbattle/tests/translations_test.py:37 +#: squirrelbattle/tests/translations_test.py:41 msgid "Key to validate a menu" msgstr "" #: squirrelbattle/settings.py:31 squirrelbattle/tests/translations_test.py:39 +#: squirrelbattle/tests/translations_test.py:43 msgid "Texture pack" msgstr "" #: squirrelbattle/settings.py:32 squirrelbattle/tests/translations_test.py:40 +#: squirrelbattle/tests/translations_test.py:44 msgid "Language" msgstr "" -#: squirrelbattle/interfaces.py:407 +#: squirrelbattle/interfaces.py:407 squirrelbattle/interfaces.py:412 #, python-brace-format msgid "{name} dies." msgstr "" + +#: squirrelbattle/tests/translations_test.py:47 +msgid "player" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:49 +msgid "tiger" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:50 +msgid "hedgehog" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:51 +msgid "rabbit" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:52 +msgid "teddy bear" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:54 +msgid "bomb" +msgstr "" + +#: squirrelbattle/tests/translations_test.py:55 +msgid "heart" +msgstr "" diff --git a/locale/fr/LC_MESSAGES/squirrelbattle.mo b/locale/fr/LC_MESSAGES/squirrelbattle.mo index bc9146e56582ef46663f44ca84d8b24c1f344325..12e6fe990a48a5dcee90cc5a5049f39393074960 100644 GIT binary patch delta 938 zcmXxiKWGzS7{~D^?U~l9Rnz#VYBdcM8Z1%lBnkylP{Bng9p%oP$w`xomqe%{w>b#n za5~vt0)k){XSIVU=-?m@oeB;*h?5Tf`TpYF!@ck4-rSq#{d>3YtQc<;oJU5KDTgR? zIkRJUdWeeni4Ois{exq)hlkDf;y8}t460uh_uzc$1ysK)IDt1&{qNy%v)B?|^8D}` zmEbKNzz?Zk@gVIyANOM!mEaUE;aS{{t9Ty!Y5NEA*k7tG=uqi@W2o^a2F47=i&iv^ zJT^zAgePzxF5na{sm<>6Pzml+jo?EZOaL{}KJwT)mA=2jS^S7c@po#4j}^wZMP7Dd zj2H0%ZpF{I4L4BTpkh+? zGX3xd$zku)_9xsydjlu&8_r^$ZDT_QlPx0i8w|{e4R%gfNIRRwVP1Aqv`e}pWu1Q( zO03YpS?C^U#yWS!^na{?C5l$9&;`>G=)84QigAi2tzmTC6U+omsm)^d*-o zB`2M!1utxR*6`h^OI@q`jj(R*Wp~AoEOI?B=vvpW)mBO#U920_`TcgwZTfdgwZQLG z*A|_Yb4f{jySkqAB5S8gf5hy{pwnU;5x|Bgi6ir$UVvCayZW7ccHMIoM(h&59 zmWZIezn~gw)Fr5?rSG}k3+H|Aeeb?^-Z}R!(g@c-!p^xcrim!gCgzDp9~Z{DU&O(@ zwSc{>cW@l{u?LUs^9GKwKDAz=i3yRqw3u{rBihwTG>7^#F>4BESnuH^ z)=)pt#4WtUe*D2z^zpa4&f)|Xa26}Nrl>R2eAfYyAo=B%iN4^WCVEEQ@MboMd|`}r z3l}iLLv;n?SjHi|z#QIS2*0rp|4`o#20QO1th*Q|znn19jrUl?CmhBl$~?pzY61_Z z@C9S|j`ozOq*E=$nf8MjG}nAfJ4%C0VdeoBJ;uDAi4Oe%9hyLsg$ZppIb?*;iu4>K zgmy~@4KZVo>wuk$_v>%_qS>l@a8z}RrE;lSDlW?Q+NPV_$hhfDGVLt~Do(Q\n" "Language-Team: LANGUAGE \n" @@ -25,12 +25,12 @@ msgstr "Inventaire :" msgid "YOU ARE DEAD" msgstr "VOUS ÊTES MORT" -#: squirrelbattle/interfaces.py:394 +#: squirrelbattle/interfaces.py:394 squirrelbattle/interfaces.py:398 #, python-brace-format msgid "{name} hits {opponent}." msgstr "{name} frappe {opponent}." -#: squirrelbattle/interfaces.py:405 +#: squirrelbattle/interfaces.py:405 squirrelbattle/interfaces.py:410 #, python-brace-format msgid "{name} takes {amount} damage." msgstr "{name} prend {amount} points de dégât." @@ -89,50 +89,89 @@ msgstr "" "Votre sauvegarde semble corrompue. Elle a été supprimée." #: squirrelbattle/settings.py:21 squirrelbattle/tests/translations_test.py:21 +#: squirrelbattle/tests/translations_test.py:25 msgid "Main key to move up" msgstr "Touche principale pour aller vers le haut" #: squirrelbattle/settings.py:22 squirrelbattle/tests/translations_test.py:23 +#: squirrelbattle/tests/translations_test.py:27 msgid "Secondary key to move up" msgstr "Touche secondaire pour aller vers le haut" #: squirrelbattle/settings.py:23 squirrelbattle/tests/translations_test.py:25 +#: squirrelbattle/tests/translations_test.py:29 msgid "Main key to move down" msgstr "Touche principale pour aller vers le bas" #: squirrelbattle/settings.py:24 squirrelbattle/tests/translations_test.py:27 +#: squirrelbattle/tests/translations_test.py:31 msgid "Secondary key to move down" msgstr "Touche secondaire pour aller vers le bas" #: squirrelbattle/settings.py:25 squirrelbattle/tests/translations_test.py:29 +#: squirrelbattle/tests/translations_test.py:33 msgid "Main key to move left" msgstr "Touche principale pour aller vers la gauche" #: squirrelbattle/settings.py:26 squirrelbattle/tests/translations_test.py:31 +#: squirrelbattle/tests/translations_test.py:35 msgid "Secondary key to move left" msgstr "Touche secondaire pour aller vers la gauche" #: squirrelbattle/settings.py:27 squirrelbattle/tests/translations_test.py:33 +#: squirrelbattle/tests/translations_test.py:37 msgid "Main key to move right" msgstr "Touche principale pour aller vers la droite" #: squirrelbattle/settings.py:29 squirrelbattle/tests/translations_test.py:35 +#: squirrelbattle/tests/translations_test.py:39 msgid "Secondary key to move right" msgstr "Touche secondaire pour aller vers la droite" #: squirrelbattle/settings.py:30 squirrelbattle/tests/translations_test.py:37 +#: squirrelbattle/tests/translations_test.py:41 msgid "Key to validate a menu" msgstr "Touche pour valider un menu" #: squirrelbattle/settings.py:31 squirrelbattle/tests/translations_test.py:39 +#: squirrelbattle/tests/translations_test.py:43 msgid "Texture pack" msgstr "Pack de textures" #: squirrelbattle/settings.py:32 squirrelbattle/tests/translations_test.py:40 +#: squirrelbattle/tests/translations_test.py:44 msgid "Language" msgstr "Langue" -#: squirrelbattle/interfaces.py:407 +#: squirrelbattle/interfaces.py:407 squirrelbattle/interfaces.py:412 #, python-brace-format msgid "{name} dies." msgstr "{name} meurt." + +#: squirrelbattle/tests/translations_test.py:47 +msgid "player" +msgstr "joueur" + +#: squirrelbattle/tests/translations_test.py:49 +msgid "tiger" +msgstr "tigre" + +#: squirrelbattle/tests/translations_test.py:50 +msgid "hedgehog" +msgstr "hérisson" + +#: squirrelbattle/tests/translations_test.py:51 +msgid "rabbit" +msgstr "lapin" + +#: squirrelbattle/tests/translations_test.py:52 +msgid "teddy bear" +msgstr "nounours" + +#: squirrelbattle/tests/translations_test.py:54 +msgid "bomb" +msgstr "bombe" + +#: squirrelbattle/tests/translations_test.py:55 +msgid "heart" +msgstr "cœur" diff --git a/squirrelbattle/interfaces.py b/squirrelbattle/interfaces.py index 78c1a15..90e5d69 100644 --- a/squirrelbattle/interfaces.py +++ b/squirrelbattle/interfaces.py @@ -315,6 +315,10 @@ class Entity: from squirrelbattle.entities.items import Item return isinstance(self, Item) + @property + def translated_name(self) -> str: + return _(self.name.replace("_", " ")) + @staticmethod def get_all_entity_classes(): """ @@ -392,8 +396,9 @@ class FightingEntity(Entity): Deals damage to the opponent, based on the stats """ return _("{name} hits {opponent}.")\ - .format(name=self.name, opponent=opponent.name) + " "\ - + opponent.take_damage(self, self.strength) + .format(name=_(self.translated_name.capitalize()), + opponent=_(opponent.translated_name)) + " " + \ + opponent.take_damage(self, self.strength) def take_damage(self, attacker: "Entity", amount: int) -> str: """ @@ -403,8 +408,9 @@ class FightingEntity(Entity): if self.health <= 0: self.die() return _("{name} takes {amount} damage.")\ - .format(name=self.name, amount=str(amount)) \ - + (" " + _("{name} dies.").format(name=self.name) + .format(name=self.translated_name.capitalize(), amount=str(amount))\ + + (" " + _("{name} dies.") + .format(name=self.translated_name.capitalize()) if self.health <= 0 else "") def die(self) -> None: diff --git a/squirrelbattle/tests/translations_test.py b/squirrelbattle/tests/translations_test.py index 0d190d6..1931224 100644 --- a/squirrelbattle/tests/translations_test.py +++ b/squirrelbattle/tests/translations_test.py @@ -7,9 +7,9 @@ class TestTranslations(unittest.TestCase): def setUp(self) -> None: setlocale("fr") - def test_translations(self) -> None: + def test_main_menu_translation(self) -> None: """ - Ensure that some strings are well-translated. + Ensure that the main menu is translated. """ self.assertEqual(_("New game"), "Nouvelle partie") self.assertEqual(_("Resume"), "Continuer") @@ -18,6 +18,10 @@ class TestTranslations(unittest.TestCase): self.assertEqual(_("Settings"), "Paramètres") self.assertEqual(_("Exit"), "Quitter") + def test_settings_menu_translation(self) -> None: + """ + Ensure that the settings menu is translated. + """ self.assertEqual(_("Main key to move up"), "Touche principale pour aller vers le haut") self.assertEqual(_("Secondary key to move up"), @@ -38,3 +42,14 @@ class TestTranslations(unittest.TestCase): "Touche pour valider un menu") self.assertEqual(_("Texture pack"), "Pack de textures") self.assertEqual(_("Language"), "Langue") + + def test_entities_translation(self) -> None: + self.assertEqual(_("player"), "joueur") + + self.assertEqual(_("tiger"), "tigre") + self.assertEqual(_("hedgehog"), "hérisson") + self.assertEqual(_("rabbit"), "lapin") + self.assertEqual(_("teddy bear"), "nounours") + + self.assertEqual(_("bomb"), "bombe") + self.assertEqual(_("heart"), "cœur") From 138b2c6d54c8a4df83f56d4057238730427878b3 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Sat, 28 Nov 2020 01:25:35 +0100 Subject: [PATCH 11/21] Logs are capitalized --- squirrelbattle/tests/entities_test.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/squirrelbattle/tests/entities_test.py b/squirrelbattle/tests/entities_test.py index 8f4e0c2..371bfc7 100644 --- a/squirrelbattle/tests/entities_test.py +++ b/squirrelbattle/tests/entities_test.py @@ -46,10 +46,10 @@ class TestEntities(unittest.TestCase): self.assertEqual(entity.strength, 2) for _ in range(9): self.assertEqual(entity.hit(entity), - "tiger hits tiger. tiger takes 2 damage.") + "Tiger hits tiger. Tiger takes 2 damage.") self.assertFalse(entity.dead) - self.assertEqual(entity.hit(entity), "tiger hits tiger. " - + "tiger takes 2 damage. tiger dies.") + self.assertEqual(entity.hit(entity), "Tiger hits tiger. " + + "Tiger takes 2 damage. Tiger dies.") self.assertTrue(entity.dead) entity = Rabbit() @@ -70,8 +70,8 @@ class TestEntities(unittest.TestCase): self.assertTrue(entity.y == 2 and entity.x == 6) self.assertEqual(old_health - entity.strength, self.player.health) self.assertEqual(self.map.logs.messages[-1], - f"{entity.name} hits {self.player.name}. \ -{self.player.name} takes {entity.strength} damage.") + f"{entity.name.capitalize()} hits {self.player.name}. \ +{self.player.name.capitalize()} takes {entity.strength} damage.") # Fight the rabbit old_health = entity.health From 7d026044071ce214bb50d1648ca981fb4327a85e Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Sat, 28 Nov 2020 01:59:52 +0100 Subject: [PATCH 12/21] Clean the translation module --- squirrelbattle/game.py | 4 +- squirrelbattle/menus.py | 4 +- squirrelbattle/tests/translations_test.py | 4 +- squirrelbattle/translations.py | 52 +++++++++++++++-------- 4 files changed, 40 insertions(+), 24 deletions(-) diff --git a/squirrelbattle/game.py b/squirrelbattle/game.py index 09f1328..44ad349 100644 --- a/squirrelbattle/game.py +++ b/squirrelbattle/game.py @@ -14,7 +14,7 @@ from .interfaces import Map, Logs from .resources import ResourceManager from .settings import Settings from . import menus -from .translations import gettext as _, setlocale +from .translations import gettext as _, Translator from typing import Callable @@ -35,7 +35,7 @@ class Game: self.settings = Settings() self.settings.load_settings() self.settings.write_settings() - setlocale(self.settings.LOCALE) + Translator.setlocale(self.settings.LOCALE) self.main_menu = menus.MainMenu() self.settings_menu = menus.SettingsMenu() self.settings_menu.update_values(self.settings) diff --git a/squirrelbattle/menus.py b/squirrelbattle/menus.py index 3f6f7a0..1fba7ea 100644 --- a/squirrelbattle/menus.py +++ b/squirrelbattle/menus.py @@ -7,7 +7,7 @@ from typing import Any, Optional from .display.texturepack import TexturePack from .enums import GameMode, KeyValues, DisplayActions from .settings import Settings -from .translations import gettext as _, setlocale +from .translations import gettext as _, Translator class Menu: @@ -99,7 +99,7 @@ class SettingsMenu(Menu): elif option == "LOCALE": game.settings.LOCALE = 'fr' if game.settings.LOCALE == 'en'\ else 'en' - setlocale(game.settings.LOCALE) + Translator.setlocale(game.settings.LOCALE) game.settings.write_settings() self.update_values(game.settings) else: diff --git a/squirrelbattle/tests/translations_test.py b/squirrelbattle/tests/translations_test.py index 1931224..742edea 100644 --- a/squirrelbattle/tests/translations_test.py +++ b/squirrelbattle/tests/translations_test.py @@ -1,11 +1,11 @@ import unittest -from squirrelbattle.translations import gettext as _, setlocale +from squirrelbattle.translations import gettext as _, Translator class TestTranslations(unittest.TestCase): def setUp(self) -> None: - setlocale("fr") + Translator.setlocale("fr") def test_main_menu_translation(self) -> None: """ diff --git a/squirrelbattle/translations.py b/squirrelbattle/translations.py index fa8196d..47ec9fb 100644 --- a/squirrelbattle/translations.py +++ b/squirrelbattle/translations.py @@ -1,28 +1,44 @@ # Copyright (C) 2020 by ÿnérant, eichhornchen, nicomarg, charlse # SPDX-License-Identifier: GPL-3.0-or-later -import gettext +import gettext as gt +from typing import Any, List -SUPPORTED_LOCALES = ["en", "fr"] -DEFAULT_LOCALE = "en" +class Translator: + """ + This module uses gettext to translate strings. + Translator.setlocale defines the language of the strings, + then gettext() translates the message. + """ + SUPPORTED_LOCALES: List[str] = ["en", "fr"] + locale: str = "en" + translators: dict = {} -_current_locale = DEFAULT_LOCALE + for language in SUPPORTED_LOCALES: + translators[language] = gt.translation( + "squirrelbattle", + localedir="locale", + languages=[language], + ) -_TRANSLATORS = dict() -for language in SUPPORTED_LOCALES: - _TRANSLATORS[language] = gettext.translation("squirrelbattle", - localedir="locale", - languages=[language]) + @classmethod + def setlocale(cls, lang: str) -> None: + """ + Define the language used to translate the game. + The language must be supported, otherwise nothing is done. + """ + lang = lang[:2] + if lang in cls.SUPPORTED_LOCALES: + cls.locale = lang + + @classmethod + def get_translator(cls) -> Any: + return cls.translators.get(cls.locale) def gettext(message: str) -> str: - return _TRANSLATORS.get(_current_locale, - _TRANSLATORS.get("en")).gettext(message) - - -def setlocale(lang: str) -> None: - global _current_locale - lang = lang[:2] - if lang in SUPPORTED_LOCALES: - _current_locale = lang + """ + Translate a message. + """ + return Translator.get_translator().gettext(message) From ffc8b904417fdb23def673a097ade06fea0003d8 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Sat, 28 Nov 2020 02:54:04 +0100 Subject: [PATCH 13/21] Create functions that call xgettext or msgfmt --- locale/en/LC_MESSAGES/squirrelbattle.po | 10 ++++----- locale/fr/LC_MESSAGES/squirrelbattle.po | 10 ++++----- squirrelbattle/translations.py | 27 +++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/locale/en/LC_MESSAGES/squirrelbattle.po b/locale/en/LC_MESSAGES/squirrelbattle.po index d77e823..21e45e6 100644 --- a/locale/en/LC_MESSAGES/squirrelbattle.po +++ b/locale/en/LC_MESSAGES/squirrelbattle.po @@ -1,14 +1,14 @@ # SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR ÿnérant, eichhornchen, nicomarg, charlse +# This file is distributed under the same license as the squirrelbattle package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-11-27 22:31+0100\n" +"Project-Id-Version: squirrelbattle 3.14.1\n" +"Report-Msgid-Bugs-To: squirrel-battle@crans.org\n" +"POT-Creation-Date: 2020-11-28 02:50+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/locale/fr/LC_MESSAGES/squirrelbattle.po b/locale/fr/LC_MESSAGES/squirrelbattle.po index fa4e1b0..b14ef50 100644 --- a/locale/fr/LC_MESSAGES/squirrelbattle.po +++ b/locale/fr/LC_MESSAGES/squirrelbattle.po @@ -1,14 +1,14 @@ # SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR ÿnérant, eichhornchen, nicomarg, charlse +# This file is distributed under the same license as the squirrelbattle package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-11-27 22:31+0100\n" +"Project-Id-Version: squirrelbattle 3.14.1\n" +"Report-Msgid-Bugs-To: squirrel-battle@crans.org\n" +"POT-Creation-Date: 2020-11-28 02:50+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/squirrelbattle/translations.py b/squirrelbattle/translations.py index 47ec9fb..1cee88b 100644 --- a/squirrelbattle/translations.py +++ b/squirrelbattle/translations.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later import gettext as gt +import subprocess from typing import Any, List @@ -36,6 +37,32 @@ class Translator: def get_translator(cls) -> Any: return cls.translators.get(cls.locale) + @classmethod + def makemessages(cls) -> None: + for language in cls.SUPPORTED_LOCALES: + args = ["find", "squirrelbattle/", "-iname", "*.py"] + find = subprocess.Popen(args, stdout=subprocess.PIPE) + args = ["xargs", "xgettext", "--from-code", "utf-8", + "--join-existing", + "--add-comments", + "--package-name=squirrelbattle", + "--package-version=3.14.1", + "--copyright-holder=ÿnérant, eichhornchen, " + "nicomarg, charlse", + "--msgid-bugs-address=squirrel-battle@crans.org", + "-o", f"locale/{language}/LC_MESSAGES/squirrelbattle.po"] + print(f"Make {language} messages...") + subprocess.Popen(args, stdin=find.stdout) + + @classmethod + def compilemessages(cls) -> None: + for language in cls.SUPPORTED_LOCALES: + args = ["msgfmt", "--check-format", + "-o", f"locale/{language}/LC_MESSAGES/squirrelbattle.mo", + f"locale/{language}/LC_MESSAGES/squirrelbattle.po"] + print(f"Compiling {language} messages...") + subprocess.Popen(args) + def gettext(message: str) -> str: """ From 8aad15f07b6821e024665323049ac5d49c92688d Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Sat, 28 Nov 2020 03:04:28 +0100 Subject: [PATCH 14/21] Move translation files in the module --- .../locale}/en/LC_MESSAGES/squirrelbattle.mo | Bin 337 -> 368 bytes .../locale}/en/LC_MESSAGES/squirrelbattle.po | 2 +- .../locale}/fr/LC_MESSAGES/squirrelbattle.mo | Bin 2607 -> 2638 bytes .../locale}/fr/LC_MESSAGES/squirrelbattle.po | 0 squirrelbattle/translations.py | 21 +++++++++++------- 5 files changed, 14 insertions(+), 9 deletions(-) rename {locale => squirrelbattle/locale}/en/LC_MESSAGES/squirrelbattle.mo (59%) rename {locale => squirrelbattle/locale}/en/LC_MESSAGES/squirrelbattle.po (99%) rename {locale => squirrelbattle/locale}/fr/LC_MESSAGES/squirrelbattle.mo (84%) rename {locale => squirrelbattle/locale}/fr/LC_MESSAGES/squirrelbattle.po (100%) diff --git a/locale/en/LC_MESSAGES/squirrelbattle.mo b/squirrelbattle/locale/en/LC_MESSAGES/squirrelbattle.mo similarity index 59% rename from locale/en/LC_MESSAGES/squirrelbattle.mo rename to squirrelbattle/locale/en/LC_MESSAGES/squirrelbattle.mo index 6c5906d1cd061dff54de8b533942893de34efc9e..14164ec0ffb6694d6c55f833f37252bf09f9cc75 100644 GIT binary patch delta 84 zcmcb}^nq!D3ZvOXRSnnT!qUv5qSTzE#FCPnR0U%_LlZqiuAtO{{Gt+F-{SPl6kVs% d^kUtRd@BW*T3v`@hvcHfykfolqV$Qy_W;)<9*O_} delta 53 zcmeysbdhO-3ZwW$RSmTOM`v$GcUOfl*Pviee?P9E)Pnq?5?$Zo^vo1pr_%Id-H?1M Jg^82y0RXnd5qJOq diff --git a/locale/en/LC_MESSAGES/squirrelbattle.po b/squirrelbattle/locale/en/LC_MESSAGES/squirrelbattle.po similarity index 99% rename from locale/en/LC_MESSAGES/squirrelbattle.po rename to squirrelbattle/locale/en/LC_MESSAGES/squirrelbattle.po index 21e45e6..9600c79 100644 --- a/locale/en/LC_MESSAGES/squirrelbattle.po +++ b/squirrelbattle/locale/en/LC_MESSAGES/squirrelbattle.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: squirrelbattle 3.14.1\n" "Report-Msgid-Bugs-To: squirrel-battle@crans.org\n" -"POT-Creation-Date: 2020-11-28 02:50+0100\n" +"POT-Creation-Date: 2020-11-28 03:01+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/locale/fr/LC_MESSAGES/squirrelbattle.mo b/squirrelbattle/locale/fr/LC_MESSAGES/squirrelbattle.mo similarity index 84% rename from locale/fr/LC_MESSAGES/squirrelbattle.mo rename to squirrelbattle/locale/fr/LC_MESSAGES/squirrelbattle.mo index 12e6fe990a48a5dcee90cc5a5049f39393074960..eb2e033a3be0be6f3613020253fa56fa6f3334af 100644 GIT binary patch delta 359 zcmZ24a!zD}4r9F;BLhPzD+2=?0|UbvAi)l#Hv?%NAiWz%O9SZ>KpKb`o&X7u{A(bs z0i-_zX>A}a0~7?&9za?XNS6RBYJs`Bn-rwYm_+4#`D{dBuA9Md_Q@vo^2*03~%f A8vpr)_4~CeqbJTp}`{xN(d=oMIFg$dCg??Vm7#S4`o@GRbC= zzKH=ev4lg^@s3`6qPqWfi}?$Pc>X~Ks(=ovgA?rG9D^7qrHvU>4@{B2%hGa#4B1im zlkBbaBN8DOtG}V2{-Ki+Ve(=jfv#=VUULL$xqLZSFk&sE-Y8ZpqnQ@op0&R73xSj+ AjQ{`u diff --git a/locale/fr/LC_MESSAGES/squirrelbattle.po b/squirrelbattle/locale/fr/LC_MESSAGES/squirrelbattle.po similarity index 100% rename from locale/fr/LC_MESSAGES/squirrelbattle.po rename to squirrelbattle/locale/fr/LC_MESSAGES/squirrelbattle.po diff --git a/squirrelbattle/translations.py b/squirrelbattle/translations.py index 1cee88b..7a0e524 100644 --- a/squirrelbattle/translations.py +++ b/squirrelbattle/translations.py @@ -3,6 +3,7 @@ import gettext as gt import subprocess +from pathlib import Path from typing import Any, List @@ -19,7 +20,7 @@ class Translator: for language in SUPPORTED_LOCALES: translators[language] = gt.translation( "squirrelbattle", - localedir="locale", + localedir=Path(__file__).parent / "locale", languages=[language], ) @@ -38,10 +39,11 @@ class Translator: return cls.translators.get(cls.locale) @classmethod - def makemessages(cls) -> None: + def makemessages(cls) -> None: # pragma: no cover for language in cls.SUPPORTED_LOCALES: - args = ["find", "squirrelbattle/", "-iname", "*.py"] - find = subprocess.Popen(args, stdout=subprocess.PIPE) + args = ["find", "squirrelbattle", "-iname", "*.py"] + find = subprocess.Popen(args, cwd=Path(__file__).parent.parent, + stdout=subprocess.PIPE) args = ["xargs", "xgettext", "--from-code", "utf-8", "--join-existing", "--add-comments", @@ -50,16 +52,19 @@ class Translator: "--copyright-holder=ÿnérant, eichhornchen, " "nicomarg, charlse", "--msgid-bugs-address=squirrel-battle@crans.org", - "-o", f"locale/{language}/LC_MESSAGES/squirrelbattle.po"] + "-o", Path(__file__).parent / "locale" / language + / "LC_MESSAGES" / "squirrelbattle.po"] print(f"Make {language} messages...") subprocess.Popen(args, stdin=find.stdout) @classmethod - def compilemessages(cls) -> None: + def compilemessages(cls) -> None: # pragma: no cover for language in cls.SUPPORTED_LOCALES: args = ["msgfmt", "--check-format", - "-o", f"locale/{language}/LC_MESSAGES/squirrelbattle.mo", - f"locale/{language}/LC_MESSAGES/squirrelbattle.po"] + "-o", Path(__file__).parent / "locale" / language + / "LC_MESSAGES" / "squirrelbattle.mo", + Path(__file__).parent / "locale" / language + / "LC_MESSAGES" / "squirrelbattle.po"] print(f"Compiling {language} messages...") subprocess.Popen(args) From 7c0cf3e029d408e857e7172a0567af387216eed2 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Sat, 28 Nov 2020 03:21:20 +0100 Subject: [PATCH 15/21] CLI to manage messages --- main.py | 18 +++++++++++++++++- squirrelbattle/translations.py | 22 ++++++++++++++-------- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/main.py b/main.py index e8c333e..fbbbb35 100755 --- a/main.py +++ b/main.py @@ -2,8 +2,24 @@ # Copyright (C) 2020 by ÿnérant, eichhornchen, nicomarg, charlse # SPDX-License-Identifier: GPL-3.0-or-later +import argparse +import sys from squirrelbattle.bootstrap import Bootstrap +from squirrelbattle.translations import Translator if __name__ == "__main__": - Bootstrap.run_game() + parser = argparse.ArgumentParser() + + parser.add_argument("--makemessages", "-mm", action="store_true", + help="Extract translatable strings") + parser.add_argument("--compilemessages", "-cm", action="store_true", + help="Compile translatable strings") + + args = parser.parse_args(sys.argv[1:]) + if args.makemessages: + Translator.makemessages() + elif args.compilemessages: + Translator.compilemessages() + else: + Bootstrap.run_game() diff --git a/squirrelbattle/translations.py b/squirrelbattle/translations.py index 7a0e524..dfd3cf3 100644 --- a/squirrelbattle/translations.py +++ b/squirrelbattle/translations.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later import gettext as gt +import os import subprocess from pathlib import Path from typing import Any, List @@ -18,11 +19,14 @@ class Translator: translators: dict = {} for language in SUPPORTED_LOCALES: - translators[language] = gt.translation( - "squirrelbattle", - localedir=Path(__file__).parent / "locale", - languages=[language], - ) + dir = Path(__file__).parent / "locale" / language / "LC_MESSAGES" + dir.mkdir(parents=True) if not dir.is_dir() else None + if os.path.isfile(dir / "squirrelbattle.mo"): + translators[language] = gt.translation( + "squirrelbattle", + localedir=Path(__file__).parent / "locale", + languages=[language], + ) @classmethod def setlocale(cls, lang: str) -> None: @@ -41,19 +45,21 @@ class Translator: @classmethod def makemessages(cls) -> None: # pragma: no cover for language in cls.SUPPORTED_LOCALES: + file_name = Path(__file__).parent / "locale" / language \ + / "LC_MESSAGES" / "squirrelbattle.po" args = ["find", "squirrelbattle", "-iname", "*.py"] find = subprocess.Popen(args, cwd=Path(__file__).parent.parent, stdout=subprocess.PIPE) args = ["xargs", "xgettext", "--from-code", "utf-8", - "--join-existing", "--add-comments", "--package-name=squirrelbattle", "--package-version=3.14.1", "--copyright-holder=ÿnérant, eichhornchen, " "nicomarg, charlse", "--msgid-bugs-address=squirrel-battle@crans.org", - "-o", Path(__file__).parent / "locale" / language - / "LC_MESSAGES" / "squirrelbattle.po"] + "-o", file_name] + if file_name.is_file(): + args.append("--join-existing") print(f"Make {language} messages...") subprocess.Popen(args, stdin=find.stdout) From 5ce62c15f7a4f771b094cb420cf0dc5ab9dc77af Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Sat, 28 Nov 2020 03:23:04 +0100 Subject: [PATCH 16/21] Include locale files in Python setup script --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 6287f7d..a9b8379 100644 --- a/setup.py +++ b/setup.py @@ -36,7 +36,7 @@ setup( ], python_requires='>=3.6', include_package_data=True, - package_data={"squirrelbattle": ["assets/*"]}, + package_data={"squirrelbattle": ["assets/*", "locale/*"]}, entry_points={ "console_scripts": [ "squirrel-battle = squirrelbattle.bootstrap:Bootstrap.run_game", From a34dae2ad0fe0db769bb08605976b46819af8b11 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Sat, 28 Nov 2020 13:49:28 +0100 Subject: [PATCH 17/21] Compile messages on setup --- .gitignore | 3 +++ setup.py | 14 ++++++++++++-- .../locale/en/LC_MESSAGES/squirrelbattle.mo | Bin 368 -> 0 bytes .../locale/fr/LC_MESSAGES/squirrelbattle.mo | Bin 2638 -> 0 bytes 4 files changed, 15 insertions(+), 2 deletions(-) delete mode 100644 squirrelbattle/locale/en/LC_MESSAGES/squirrelbattle.mo delete mode 100644 squirrelbattle/locale/fr/LC_MESSAGES/squirrelbattle.mo diff --git a/.gitignore b/.gitignore index f30aa49..8499d7c 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,6 @@ save.json # Don't commit docs output docs/_build + +# Don't commit compiled messages +*.mo diff --git a/setup.py b/setup.py index a9b8379..00bd56b 100644 --- a/setup.py +++ b/setup.py @@ -3,13 +3,23 @@ # Copyright (C) 2020 by ÿnérant, eichhornchen, nicomarg, charlse # SPDX-License-Identifier: GPL-3.0-or-later -import os +import subprocess from setuptools import find_packages, setup with open("README.md", "r") as f: long_description = f.read() +# Compile messages +for language in ["en", "fr"]: + args = ["msgfmt", "--check-format", + "-o", f"squirrelbattle/locale/{language}/LC_MESSAGES" + "/squirrelbattle.mo", + f"squirrelbattle/locale/{language}/LC_MESSAGES" + "/squirrelbattle.po"] + print(f"Compiling {language} messages...") + subprocess.Popen(args) + setup( name="squirrel-battle", version="3.14.1", @@ -36,7 +46,7 @@ setup( ], python_requires='>=3.6', include_package_data=True, - package_data={"squirrelbattle": ["assets/*", "locale/*"]}, + package_data={"squirrelbattle": ["assets/*", "locale/*/*/*"]}, entry_points={ "console_scripts": [ "squirrel-battle = squirrelbattle.bootstrap:Bootstrap.run_game", diff --git a/squirrelbattle/locale/en/LC_MESSAGES/squirrelbattle.mo b/squirrelbattle/locale/en/LC_MESSAGES/squirrelbattle.mo deleted file mode 100644 index 14164ec0ffb6694d6c55f833f37252bf09f9cc75..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 368 zcmYL^zfQw25Qjl9Wn^aXzy=qnK&Y5Msv&NPWH(isBEjaSCKv^~*e-$x;q`bHE63^1&Ug2-xBIA*gv=7EvO2Yfbc(2=~ zim}z?G##9!gQV1J=Of6_m=)Y^ngEsSUHFqnwO2Nz&Ns=dfKq>$?n}s2)Ra7OR)Q=b zW8}V|GCzDOraTcUM5wy9Rz>G2883t&QzkjN;*#ZJ#Img9^Z5;`w%MpgL#5RlC4x;S z3pPPdh*4|0sl7uYBy-R4x diff --git a/squirrelbattle/locale/fr/LC_MESSAGES/squirrelbattle.mo b/squirrelbattle/locale/fr/LC_MESSAGES/squirrelbattle.mo deleted file mode 100644 index eb2e033a3be0be6f3613020253fa56fa6f3334af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2638 zcmbuA&yQ3^5XW0V)ImYPpNQH^Ld3uuSTTkSC=AR1gEKqp%q(QRn4WpPZyMg~esuR6 z7zzIXCllh$c<|&Hd ze*^Jj|6q6s+=zkp_hejD5a{toU1cVdxv8hjP>;8yTs@C^6`_$YV>+zf7j(X@XnNc#>= z7=pC_1CZpt0^bL}0iOViP|^h(AnCsW!gO|P!tX)+*bf-U-k&DxzkpD|ex1z!03XNv zFYtMAGn};t+zrAVBOOnHFn4q=!Zq?6r4RXa+FrsRPok5LC_i?gPaEl_M(0i&4sNH%A98jHTP{E~2d$z(d@Mswd)jwd3W$<;)^EqUK$JXA6~${NyT*w++2 z46ErnYs3-v8`)=gTYPdz0#3mO_NAE&T(NSPn2_5=5P{BwA{fgzNBKA z&n+&`os@|qSK}fbV{MlDJg;~j8P7u*OE1GbYst$#gT|CX)#^%qrdgjGsp4>jhA3^7 z9lu)hL?^VY(z;k*;KfFnm&(NwYn!Cax>8t=F^pu_L~QJQW<|S=?0_X6yo#h{ zS2Tijm0a)g(@9r($FG<)H5#dOb$Q*33lbkhf*^YA5ec#=&*rT;53_?x7@U>XDWePA zUCb0N6Ssx;vE&Eyv#;l8a}Ajq>w}t$R2Ur3A{VsGifk|zKGv~9yS%YcZoVEgWKWUG zpo9!A@Wpbm5!C8IsmM>)3$@DLck6TITva$9v}ju_kopCFa-mw~bH!SjA1T+0mFlr# zsnjSpn{PpMocuvcilo4+#ko@p#Z!>0R*%JsPF;~H@La7@E3e#YHh&;@!e|e#1g(Aw zdpv@=A1+qnfYM&nTLZgN*DA@h7y8=;zt=pMd=LwXbKz>2^+5X#*M28xpsZutS9(i->fft zuW#0qo%m*6Sdk1r#qAtBA+1M7Nyj_!aNtlvc+b$imlT3yY3`P9$sMkaN~$kr0-5RZ zxw9kLyCr1OhS#Zzm?X_)o|h>KQ-8ZGO|43X1A5CSPNbjm8pX=7>iATJV@LJs-m|6i zsEo^X>;Ig5w!YBh!)vW_lh^8v)~J?A*7^E6-bi;iu&BdEvvIPpSfolbjXH!E;;58a pIjvp^vdJ&ktR*YbRIXLcQY-PVXt|oDMro8i+%FssqTwe{@h?*k&%yuz From f78c73a7035c61bfc279ec451101e426e613413a Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Sat, 28 Nov 2020 14:02:23 +0100 Subject: [PATCH 18/21] Tests and the CI are compiling messages --- .gitlab-ci.yml | 6 +++- squirrelbattle/tests/game_test.py | 24 +++++++------- squirrelbattle/tests/translations_test.py | 2 ++ squirrelbattle/translations.py | 40 +++++++++++++++-------- 4 files changed, 46 insertions(+), 26 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8613258..867562b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,6 +7,7 @@ py37: stage: test image: python:3.7-alpine before_script: + - apk add --no-cache gettext - pip install tox script: tox -e py3 @@ -14,6 +15,7 @@ py38: stage: test image: python:3.8-alpine before_script: + - apk add --no-cache gettext - pip install tox script: tox -e py3 @@ -22,6 +24,7 @@ py39: stage: test image: python:3.9-alpine before_script: + - apk add --no-cache gettext - pip install tox script: tox -e py3 @@ -29,6 +32,7 @@ linters: stage: quality-assurance image: python:3-alpine before_script: + - apk add --no-cache gettext - pip install tox script: tox -e linters allow_failure: true @@ -37,7 +41,7 @@ build-deb: image: debian:buster-slim stage: build before_script: - - apt-get update && apt-get -y --no-install-recommends install build-essential debmake dh-python debhelper python3-all python3-setuptools + - apt-get update && apt-get -y --no-install-recommends install build-essential debmake dh-python debhelper gettext python3-all python3-setuptools script: - dpkg-buildpackage - mkdir build && cp ../*.deb build/ diff --git a/squirrelbattle/tests/game_test.py b/squirrelbattle/tests/game_test.py index 8f5b1c1..9c950d6 100644 --- a/squirrelbattle/tests/game_test.py +++ b/squirrelbattle/tests/game_test.py @@ -4,18 +4,16 @@ import os import unittest -from squirrelbattle.resources import ResourceManager - -from squirrelbattle.enums import DisplayActions - -from squirrelbattle.bootstrap import Bootstrap -from squirrelbattle.display.display import Display -from squirrelbattle.display.display_manager import DisplayManager -from squirrelbattle.entities.player import Player -from squirrelbattle.game import Game, KeyValues, GameMode -from squirrelbattle.menus import MainMenuValues -from squirrelbattle.settings import Settings -from squirrelbattle.translations import gettext as _ +from ..bootstrap import Bootstrap +from ..display.display import Display +from ..display.display_manager import DisplayManager +from ..entities.player import Player +from ..enums import DisplayActions +from ..game import Game, KeyValues, GameMode +from ..menus import MainMenuValues +from ..resources import ResourceManager +from ..settings import Settings +from ..translations import gettext as _, Translator class TestGame(unittest.TestCase): @@ -277,6 +275,8 @@ class TestGame(unittest.TestCase): self.assertEqual(self.game.settings.TEXTURE_PACK, "ascii") # Change language + Translator.compilemessages() + Translator.refresh_translations() self.game.settings.LOCALE = "en" self.game.handle_key_pressed(KeyValues.DOWN) self.game.handle_key_pressed(KeyValues.ENTER) diff --git a/squirrelbattle/tests/translations_test.py b/squirrelbattle/tests/translations_test.py index 742edea..6c18840 100644 --- a/squirrelbattle/tests/translations_test.py +++ b/squirrelbattle/tests/translations_test.py @@ -5,6 +5,8 @@ from squirrelbattle.translations import gettext as _, Translator class TestTranslations(unittest.TestCase): def setUp(self) -> None: + Translator.compilemessages() + Translator.refresh_translations() Translator.setlocale("fr") def test_main_menu_translation(self) -> None: diff --git a/squirrelbattle/translations.py b/squirrelbattle/translations.py index dfd3cf3..cd5b7fc 100644 --- a/squirrelbattle/translations.py +++ b/squirrelbattle/translations.py @@ -18,15 +18,20 @@ class Translator: locale: str = "en" translators: dict = {} - for language in SUPPORTED_LOCALES: - dir = Path(__file__).parent / "locale" / language / "LC_MESSAGES" - dir.mkdir(parents=True) if not dir.is_dir() else None - if os.path.isfile(dir / "squirrelbattle.mo"): - translators[language] = gt.translation( - "squirrelbattle", - localedir=Path(__file__).parent / "locale", - languages=[language], - ) + @classmethod + def refresh_translations(cls) -> None: + """ + Load compiled translations. + """ + for language in cls.SUPPORTED_LOCALES: + rep = Path(__file__).parent / "locale" / language / "LC_MESSAGES" + rep.mkdir(parents=True) if not rep.is_dir() else None + if os.path.isfile(rep / "squirrelbattle.mo"): + cls.translators[language] = gt.translation( + "squirrelbattle", + localedir=Path(__file__).parent / "locale", + languages=[language], + ) @classmethod def setlocale(cls, lang: str) -> None: @@ -40,10 +45,13 @@ class Translator: @classmethod def get_translator(cls) -> Any: - return cls.translators.get(cls.locale) + return cls.translators.get(cls.locale, gt.NullTranslations()) @classmethod def makemessages(cls) -> None: # pragma: no cover + """ + Analyse all strings in the project and extract them. + """ for language in cls.SUPPORTED_LOCALES: file_name = Path(__file__).parent / "locale" / language \ / "LC_MESSAGES" / "squirrelbattle.po" @@ -61,10 +69,13 @@ class Translator: if file_name.is_file(): args.append("--join-existing") print(f"Make {language} messages...") - subprocess.Popen(args, stdin=find.stdout) + subprocess.Popen(args, stdin=find.stdout).wait() @classmethod - def compilemessages(cls) -> None: # pragma: no cover + def compilemessages(cls) -> None: + """ + Compile translation messages from source files. + """ for language in cls.SUPPORTED_LOCALES: args = ["msgfmt", "--check-format", "-o", Path(__file__).parent / "locale" / language @@ -72,7 +83,7 @@ class Translator: Path(__file__).parent / "locale" / language / "LC_MESSAGES" / "squirrelbattle.po"] print(f"Compiling {language} messages...") - subprocess.Popen(args) + subprocess.Popen(args).wait() def gettext(message: str) -> str: @@ -80,3 +91,6 @@ def gettext(message: str) -> str: Translate a message. """ return Translator.get_translator().gettext(message) + + +Translator.refresh_translations() From aade89de7b944b98671de16175cc1a3112904a70 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Sat, 28 Nov 2020 14:10:31 +0100 Subject: [PATCH 19/21] Tests and the CI are compiling messages --- .gitlab-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 867562b..ff5c142 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -32,7 +32,6 @@ linters: stage: quality-assurance image: python:3-alpine before_script: - - apk add --no-cache gettext - pip install tox script: tox -e linters allow_failure: true From 6b09d488b63f978e77df9f5f53fb89a33df321ed Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Sat, 28 Nov 2020 16:00:17 +0100 Subject: [PATCH 20/21] Documentation on translation --- debian/control | 2 +- docs/deployment.rst | 20 ++++++-- docs/index.rst | 1 + docs/install-dev.rst | 21 +++++--- docs/translation.rst | 120 +++++++++++++++++++++++++++++++++++++++++++ setup.py | 2 +- 6 files changed, 154 insertions(+), 12 deletions(-) create mode 100644 docs/translation.rst diff --git a/debian/control b/debian/control index fc52e38..b59997d 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Source: python3-squirrel-battle Section: devel Priority: optional Maintainer: ynerant -Build-Depends: debhelper (>=10~), dh-python, python3-all, python3-setuptools +Build-Depends: debhelper (>=10~), dh-python, gettext, python3-all, python3-setuptools Depends: fonts-noto-color-emoji Standards-Version: 4.1.4 Homepage: https://gitlab.crans.org/ynerant/squirrel-battle diff --git a/docs/deployment.rst b/docs/deployment.rst index a9f58ee..6a57b58 100644 --- a/docs/deployment.rst +++ b/docs/deployment.rst @@ -34,6 +34,16 @@ paquet ainsi que des détails à fournir à PyPI : with open("README.md", "r") as f: long_description = f.read() + # Compile messages + for language in ["en", "fr"]: + args = ["msgfmt", "--check-format", + "-o", f"squirrelbattle/locale/{language}/LC_MESSAGES" + "/squirrelbattle.mo", + f"squirrelbattle/locale/{language}/LC_MESSAGES" + "/squirrelbattle.po"] + print(f"Compiling {language} messages...") + subprocess.Popen(args) + setup( name="squirrel-battle", version="3.14.1", @@ -60,7 +70,7 @@ paquet ainsi que des détails à fournir à PyPI : ], python_requires='>=3.6', include_package_data=True, - package_data={"squirrelbattle": ["assets/*"]}, + package_data={"squirrelbattle": ["assets/*", "locale/*/*/*.mo"]}, entry_points={ "console_scripts": [ "squirrel-battle = squirrelbattle.bootstrap:Bootstrap.run_game", @@ -72,6 +82,8 @@ Ce fichier contient le nom du paquet, sa version, l'auteur et son contact, sa description en une ligne et sa description longue, le lien d'accueil du projet, sa licence, ses classificateurs et son exécutable. +Il commence tout d'abord par compiler les fichiers de `traduction `_. + Le paramètre ``entry_points`` définit un exécutable nommé ``squirrel-battle``, qui permet de lancer le jeu. @@ -167,7 +179,7 @@ du dépôt Git. Le fichier ``PKGBUILD`` dispose de cette structure : url="https://gitlab.crans.org/ynerant/squirrel-battle" license=('GPLv3') depends=('python') - makedepends=('python-setuptools') + makedepends=('gettext' 'python-setuptools') depends=('noto-fonts-emoji') checkdepends=('python-tox') ssource=("git+https://gitlab.crans.org/ynerant/squirrel-battle.git") @@ -217,7 +229,7 @@ les releases, est plus ou moins similaire : url="https://gitlab.crans.org/ynerant/squirrel-battle" license=('GPLv3') depends=('python') - makedepends=('python-setuptools') + makedepends=('gettext' 'python-setuptools') depends=('noto-fonts-emoji') checkdepends=('python-tox') source=("https://gitlab.crans.org/ynerant/squirrel-battle/-/archive/v3.14.1/$pkgbase-v$pkgver.tar.gz") @@ -296,7 +308,7 @@ D'abord on installe les paquets nécessaires : .. code:: apt update - apt --no-install-recommends install build-essential debmake dh-python debhelper python3-all python3-setuptools + apt --no-install-recommends install build-essential debmake dh-python debhelper gettext python3-all python3-setuptools On peut ensuite construire le paquet : diff --git a/docs/index.rst b/docs/index.rst index ff6bcf3..1cb7d83 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -37,6 +37,7 @@ Bienvenue dans la documentation de Squirrel Battle ! install-dev tests display/index + translation deployment documentation diff --git a/docs/install-dev.rst b/docs/install-dev.rst index db611e0..973c0e0 100644 --- a/docs/install-dev.rst +++ b/docs/install-dev.rst @@ -1,16 +1,19 @@ Installation d'un environnement de développement ================================================ -Il est toujours préférable de travailler dans un environnement Python isolé du reste de son instalation. +Il est toujours préférable de travailler dans un environnement Python isolé du +reste de son instalation. 1. **Installation des dépendances de la distribution.** - Vous devez déjà installer Python et le module qui permet de créer des environnements virtuels. - On donne ci-dessous l'exemple pour une distribution basée sur Debian, mais vous pouvez facilement adapter pour ArchLinux ou autre. + Vous devez déjà installer Python et le module qui permet de créer des + environnements virtuels. + On donne ci-dessous l'exemple pour une distribution basée sur Debian, + mais vous pouvez facilement adapter pour ArchLinux ou autre. .. code:: bash $ sudo apt update - $ sudo apt install --no-install-recommends -y python3-setuptools python3-venv python3-dev git + $ sudo apt install --no-install-recommends -y python3-setuptools python3-venv python3-dev gettext git 2. **Clonage du dépot** là où vous voulez : @@ -25,7 +28,13 @@ Il est toujours préférable de travailler dans un environnement Python isolé d $ python3 -m venv env $ source env/bin/activate # entrer dans l'environnement - (env)$ pip3 install -r requirements.txt - (env)$ deactivate # sortir de l'environnement + (env) $ pip3 install -r requirements.txt + (env) $ deactivate # sortir de l'environnement + +4. **Compilation des messages de traduction.** + +.. code:: bash + + (env) $ python3 main.py --compilemessages Le lancement du jeu se fait en lançant la commande ``python3 main.py``. \ No newline at end of file diff --git a/docs/translation.rst b/docs/translation.rst new file mode 100644 index 0000000..ab3da46 --- /dev/null +++ b/docs/translation.rst @@ -0,0 +1,120 @@ +Traduction +========== + +Le jeu Squirrel Battle est entièrement traduit en anglais et en français. +La langue se choisit dans les `paramètres `_. + + +Utitisation +----------- + +Les traductions sont gérées grâce au module natif ``gettext``. Le module +``squirrelbattle.translations`` s'occupe d'installer les traductions, et de +donner les chaînes traduites. + +Pour choisir la langue, il faut appeler ``Translator.setlocale(language: str)``, +où ``language`` correspond au code à 2 lettres de la langue. + +Enfin, le module expose une fonction ``gettext(str) -> str`` qui permet de +traduire les chaînes. + +Il est courant et recommandé d'importer cette fonction sous l'alias ``_``, +afin de limiter la verbositer et de permettre de rendre facilement une chaîne +traduisible. + +.. code:: python + + from squirrelbattle.translations import gettext as _, Translator + + Translator.setlocale("fr") + print(_("I am a translatable string")) + print("I am not translatable") + +Si les traductions sont bien faites (voir ci-dessous), cela donnera : + +.. code:: + + Je suis une chaîne traduisible + I am not translatable + +À noter que si la chaîne n'est pas traduite, alors par défaut on renvoie la +chaîne elle-même. + + +Extraction des chaînes à traduire +--------------------------------- + +L'appel à ``gettext`` ne fait pas que traduire les chaînes : il est possible +également d'extraire toutes les chaînes à traduire. + +Il est nécessaire d'installer le paquet Linux ``gettext`` pour cela. + +L'utilitaire ``xgettext`` s'occupe de cette extraction. Il s'utilise de la façon +suivante : + +.. code:: bash + + xgettext --from-code utf-8 -o output_file.po source_1.py ... source_n.py + +Afin de ne pas avoir à sélectionner manuellement chaque fichier, il est possible +d'appeler directement ``python3 main.py --makemessages``. Cela a pour effet +d'exécuter pour chaque langue ```` : + +.. code:: bash + + find squirrelbattle -iname '*.py' | xargs xgettext --from-code utf-8 + --add-comments + --package-name=squirrelbattle + --package-version=3.14.1 + "--copyright-holder=ÿnérant, eichhornchen, nicomarg, charlse" + --msgid-bugs-address=squirrel-battle@crans.org + -o squirrelbattle/locale//LC_MESSAGES/squirrelbattle.po + +Les fichiers de traductions se trouvent alors dans +``squirrelbattle/locale//LC_MESSAGES/squirrelbattle.po``. + + +Traduire les chaînes +-------------------- + +Après extraction des chaînes, les chaînes à traduire se trouvent dans +``squirrelbattle/locale//LC_MESSAGES/squirrelbattle.po``, comme indiqué +ci-dessus. + +Ce fichier peut-être édité avec un utilitaire tel que ``poedit``, sur +l'interface Web sur ``_, +mais surtout manuellement avec un éditeur de texte. + +Dans ce fichier, on obtient pour chaque chaîne à traduire un paragraphe de la +forme : + +.. code:: po + + #: main.py:4 + msgid "I am a translatable string" + msgstr "Je suis une chaîne traduisible" + +Il sufift de remplir les champs ``msgstr``. + + +Compilation des chaînes +----------------------- + +Pour gagner en efficacité, les chaînes sont compilées dans un fichier avec +l'extension ``.mo``. Ce sont ces fichiers qui sont lus par le module de traduction. + +Pour compiler les traductions, c'est l'utilitaire ``msgfmt`` fourni toujours par +le paquet Linux ``gettext`` que nous utilisons. Il s'utilise assez simplement : + +.. code:: bash + + msgfmt po_file.po -o mo_file.mo + +À nouveau, il est possible de compiler automatiquement les messages en exécutant +``python3 main.py --compilemessages``. + +.. warning:: + + On ne partagera pas dans le dépôt Git les fichiers compilé. En développement, + on compilera soi-même les messages, et en production, la construction des + paquets se charge de compiler automatiquement les traductions. diff --git a/setup.py b/setup.py index 00bd56b..b9e493a 100644 --- a/setup.py +++ b/setup.py @@ -46,7 +46,7 @@ setup( ], python_requires='>=3.6', include_package_data=True, - package_data={"squirrelbattle": ["assets/*", "locale/*/*/*"]}, + package_data={"squirrelbattle": ["assets/*", "locale/*/*/*.mo"]}, entry_points={ "console_scripts": [ "squirrel-battle = squirrelbattle.bootstrap:Bootstrap.run_game", From 9f0a29302dd84691938642dd030a65a4db6eebd6 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Sat, 28 Nov 2020 16:22:06 +0100 Subject: [PATCH 21/21] Add german translation --- docs/deployment.rst | 2 +- docs/translation.rst | 2 +- setup.py | 2 +- .../locale/de/LC_MESSAGES/squirrelbattle.po | 166 ++++++++++++++++++ .../locale/en/LC_MESSAGES/squirrelbattle.po | 26 ++- .../locale/fr/LC_MESSAGES/squirrelbattle.po | 26 ++- squirrelbattle/menus.py | 2 +- squirrelbattle/tests/game_test.py | 3 + squirrelbattle/translations.py | 2 +- 9 files changed, 224 insertions(+), 7 deletions(-) create mode 100644 squirrelbattle/locale/de/LC_MESSAGES/squirrelbattle.po diff --git a/docs/deployment.rst b/docs/deployment.rst index 6a57b58..9477a10 100644 --- a/docs/deployment.rst +++ b/docs/deployment.rst @@ -35,7 +35,7 @@ paquet ainsi que des détails à fournir à PyPI : long_description = f.read() # Compile messages - for language in ["en", "fr"]: + for language in ["de", "en", "fr"]: args = ["msgfmt", "--check-format", "-o", f"squirrelbattle/locale/{language}/LC_MESSAGES" "/squirrelbattle.mo", diff --git a/docs/translation.rst b/docs/translation.rst index ab3da46..f3d2584 100644 --- a/docs/translation.rst +++ b/docs/translation.rst @@ -1,7 +1,7 @@ Traduction ========== -Le jeu Squirrel Battle est entièrement traduit en anglais et en français. +Le jeu Squirrel Battle est entièrement traduit en anglais, en français et en allement. La langue se choisit dans les `paramètres `_. diff --git a/setup.py b/setup.py index b9e493a..f051bbb 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ with open("README.md", "r") as f: long_description = f.read() # Compile messages -for language in ["en", "fr"]: +for language in ["de", "en", "fr"]: args = ["msgfmt", "--check-format", "-o", f"squirrelbattle/locale/{language}/LC_MESSAGES" "/squirrelbattle.mo", diff --git a/squirrelbattle/locale/de/LC_MESSAGES/squirrelbattle.po b/squirrelbattle/locale/de/LC_MESSAGES/squirrelbattle.po new file mode 100644 index 0000000..dfd3365 --- /dev/null +++ b/squirrelbattle/locale/de/LC_MESSAGES/squirrelbattle.po @@ -0,0 +1,166 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR ÿnérant, eichhornchen, nicomarg, charlse +# This file is distributed under the same license as the squirrelbattle package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: squirrelbattle 3.14.1\n" +"Report-Msgid-Bugs-To: squirrel-battle@crans.org\n" +"POT-Creation-Date: 2020-11-28 16:03+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: squirrelbattle/tests/game_test.py:284 squirrelbattle/tests/game_test.py:287 +#: squirrelbattle/tests/translations_test.py:16 +msgid "New game" +msgstr "Neu Spiel" + +#: squirrelbattle/tests/translations_test.py:17 +msgid "Resume" +msgstr "Weitergehen" + +#: squirrelbattle/tests/translations_test.py:18 +msgid "Load" +msgstr "Laden" + +#: squirrelbattle/tests/translations_test.py:19 +msgid "Save" +msgstr "Speichern" + +#: squirrelbattle/tests/translations_test.py:20 +msgid "Settings" +msgstr "Einstellungen" + +#: squirrelbattle/tests/translations_test.py:21 +msgid "Exit" +msgstr "Verlassen" + +#: squirrelbattle/tests/translations_test.py:27 +msgid "Main key to move up" +msgstr "Haupttaste zum Obengehen" + +#: squirrelbattle/tests/translations_test.py:29 +msgid "Secondary key to move up" +msgstr "Sekundärtaste zum Obengehen" + +#: squirrelbattle/tests/translations_test.py:31 +msgid "Main key to move down" +msgstr "Haupttaste zum Untergehen" + +#: squirrelbattle/tests/translations_test.py:33 +msgid "Secondary key to move down" +msgstr "Sekundärtaste zum Untergehen" + +#: squirrelbattle/tests/translations_test.py:35 +msgid "Main key to move left" +msgstr "Haupttaste zum Linksgehen" + +#: squirrelbattle/tests/translations_test.py:37 +msgid "Secondary key to move left" +msgstr "Sekundärtaste zum Linksgehen" + +#: squirrelbattle/tests/translations_test.py:39 +msgid "Main key to move right" +msgstr "Haupttaste zum Rechtsgehen" + +#: squirrelbattle/tests/translations_test.py:41 +msgid "Secondary key to move right" +msgstr "Sekundärtaste zum Rechtsgehen" + +#: squirrelbattle/tests/translations_test.py:43 +msgid "Key to validate a menu" +msgstr "Menütaste" + +#: squirrelbattle/tests/translations_test.py:45 +msgid "Texture pack" +msgstr "Textur-Packung" + +#: squirrelbattle/tests/translations_test.py:46 +msgid "Language" +msgstr "Sprache" + +#: squirrelbattle/tests/translations_test.py:49 +msgid "player" +msgstr "Spieler" + +#: squirrelbattle/tests/translations_test.py:51 +msgid "tiger" +msgstr "Tiger" + +#: squirrelbattle/tests/translations_test.py:52 +msgid "hedgehog" +msgstr "Igel" + +#: squirrelbattle/tests/translations_test.py:53 +msgid "rabbit" +msgstr "Kanninchen" + +#: squirrelbattle/tests/translations_test.py:54 +msgid "teddy bear" +msgstr "Teddybär" + +#: squirrelbattle/tests/translations_test.py:56 +msgid "bomb" +msgstr "Bombe" + +#: squirrelbattle/tests/translations_test.py:57 +msgid "heart" +msgstr "Herz" + +#: squirrelbattle/display/statsdisplay.py:34 +msgid "Inventory:" +msgstr "Bestand:" + +#: squirrelbattle/display/statsdisplay.py:39 +msgid "YOU ARE DEAD" +msgstr "SIE WURDEN GESTORBEN" + +#: squirrelbattle/interfaces.py:398 +#, python-brace-format +msgid "{name} hits {opponent}." +msgstr "{name} schlägt {opponent}." + +#: squirrelbattle/interfaces.py:410 +#, python-brace-format +msgid "{name} takes {amount} damage." +msgstr "{name} nimmt {amount} Schadenspunkte." + +#: squirrelbattle/interfaces.py:412 +#, python-brace-format +msgid "{name} dies." +msgstr "{name} stirbt." + +#: squirrelbattle/menus.py:71 +msgid "Back" +msgstr "Zurück" + +#: squirrelbattle/game.py:148 +msgid "" +"Some keys are missing in your save file.\n" +"Your save seems to be corrupt. It got deleted." +msgstr "" +"In Ihrer Speicherdatei fehlen einige Schlüssel.\n" +"Ihre Speicherung scheint korrupt zu sein. Es wird gelöscht." + +#: squirrelbattle/game.py:156 +msgid "" +"No player was found on this map!\n" +"Maybe you died?" +msgstr "" +"Auf dieser Karte wurde kein Spieler gefunden!\n" +"Vielleicht sind Sie gestorben?" + +#: squirrelbattle/game.py:176 +msgid "" +"The JSON file is not correct.\n" +"Your save seems corrupted. It got deleted." +msgstr "" +"Die JSON-Datei ist nicht korrekt.\n" +"Ihre Speicherung scheint korrumpiert. Sie wurde gelöscht." diff --git a/squirrelbattle/locale/en/LC_MESSAGES/squirrelbattle.po b/squirrelbattle/locale/en/LC_MESSAGES/squirrelbattle.po index 9600c79..3f563fa 100644 --- a/squirrelbattle/locale/en/LC_MESSAGES/squirrelbattle.po +++ b/squirrelbattle/locale/en/LC_MESSAGES/squirrelbattle.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: squirrelbattle 3.14.1\n" "Report-Msgid-Bugs-To: squirrel-battle@crans.org\n" -"POT-Creation-Date: 2020-11-28 03:01+0100\n" +"POT-Creation-Date: 2020-11-28 16:03+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -37,26 +37,32 @@ msgstr "" #: squirrelbattle/menus.py:45 squirrelbattle/tests/translations_test.py:14 #: squirrelbattle/tests/game_test.py:284 squirrelbattle/tests/game_test.py:287 +#: squirrelbattle/tests/translations_test.py:16 msgid "New game" msgstr "" #: squirrelbattle/menus.py:46 squirrelbattle/tests/translations_test.py:15 +#: squirrelbattle/tests/translations_test.py:17 msgid "Resume" msgstr "" #: squirrelbattle/menus.py:47 squirrelbattle/tests/translations_test.py:17 +#: squirrelbattle/tests/translations_test.py:19 msgid "Save" msgstr "" #: squirrelbattle/menus.py:48 squirrelbattle/tests/translations_test.py:16 +#: squirrelbattle/tests/translations_test.py:18 msgid "Load" msgstr "" #: squirrelbattle/menus.py:49 squirrelbattle/tests/translations_test.py:18 +#: squirrelbattle/tests/translations_test.py:20 msgid "Settings" msgstr "" #: squirrelbattle/menus.py:50 squirrelbattle/tests/translations_test.py:19 +#: squirrelbattle/tests/translations_test.py:21 msgid "Exit" msgstr "" @@ -84,56 +90,67 @@ msgstr "" #: squirrelbattle/settings.py:21 squirrelbattle/tests/translations_test.py:21 #: squirrelbattle/tests/translations_test.py:25 +#: squirrelbattle/tests/translations_test.py:27 msgid "Main key to move up" msgstr "" #: squirrelbattle/settings.py:22 squirrelbattle/tests/translations_test.py:23 #: squirrelbattle/tests/translations_test.py:27 +#: squirrelbattle/tests/translations_test.py:29 msgid "Secondary key to move up" msgstr "" #: squirrelbattle/settings.py:23 squirrelbattle/tests/translations_test.py:25 #: squirrelbattle/tests/translations_test.py:29 +#: squirrelbattle/tests/translations_test.py:31 msgid "Main key to move down" msgstr "" #: squirrelbattle/settings.py:24 squirrelbattle/tests/translations_test.py:27 #: squirrelbattle/tests/translations_test.py:31 +#: squirrelbattle/tests/translations_test.py:33 msgid "Secondary key to move down" msgstr "" #: squirrelbattle/settings.py:25 squirrelbattle/tests/translations_test.py:29 #: squirrelbattle/tests/translations_test.py:33 +#: squirrelbattle/tests/translations_test.py:35 msgid "Main key to move left" msgstr "" #: squirrelbattle/settings.py:26 squirrelbattle/tests/translations_test.py:31 #: squirrelbattle/tests/translations_test.py:35 +#: squirrelbattle/tests/translations_test.py:37 msgid "Secondary key to move left" msgstr "" #: squirrelbattle/settings.py:27 squirrelbattle/tests/translations_test.py:33 #: squirrelbattle/tests/translations_test.py:37 +#: squirrelbattle/tests/translations_test.py:39 msgid "Main key to move right" msgstr "" #: squirrelbattle/settings.py:29 squirrelbattle/tests/translations_test.py:35 #: squirrelbattle/tests/translations_test.py:39 +#: squirrelbattle/tests/translations_test.py:41 msgid "Secondary key to move right" msgstr "" #: squirrelbattle/settings.py:30 squirrelbattle/tests/translations_test.py:37 #: squirrelbattle/tests/translations_test.py:41 +#: squirrelbattle/tests/translations_test.py:43 msgid "Key to validate a menu" msgstr "" #: squirrelbattle/settings.py:31 squirrelbattle/tests/translations_test.py:39 #: squirrelbattle/tests/translations_test.py:43 +#: squirrelbattle/tests/translations_test.py:45 msgid "Texture pack" msgstr "" #: squirrelbattle/settings.py:32 squirrelbattle/tests/translations_test.py:40 #: squirrelbattle/tests/translations_test.py:44 +#: squirrelbattle/tests/translations_test.py:46 msgid "Language" msgstr "" @@ -143,29 +160,36 @@ msgid "{name} dies." msgstr "" #: squirrelbattle/tests/translations_test.py:47 +#: squirrelbattle/tests/translations_test.py:49 msgid "player" msgstr "" #: squirrelbattle/tests/translations_test.py:49 +#: squirrelbattle/tests/translations_test.py:51 msgid "tiger" msgstr "" #: squirrelbattle/tests/translations_test.py:50 +#: squirrelbattle/tests/translations_test.py:52 msgid "hedgehog" msgstr "" #: squirrelbattle/tests/translations_test.py:51 +#: squirrelbattle/tests/translations_test.py:53 msgid "rabbit" msgstr "" #: squirrelbattle/tests/translations_test.py:52 +#: squirrelbattle/tests/translations_test.py:54 msgid "teddy bear" msgstr "" #: squirrelbattle/tests/translations_test.py:54 +#: squirrelbattle/tests/translations_test.py:56 msgid "bomb" msgstr "" #: squirrelbattle/tests/translations_test.py:55 +#: squirrelbattle/tests/translations_test.py:57 msgid "heart" msgstr "" diff --git a/squirrelbattle/locale/fr/LC_MESSAGES/squirrelbattle.po b/squirrelbattle/locale/fr/LC_MESSAGES/squirrelbattle.po index b14ef50..d46cee6 100644 --- a/squirrelbattle/locale/fr/LC_MESSAGES/squirrelbattle.po +++ b/squirrelbattle/locale/fr/LC_MESSAGES/squirrelbattle.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: squirrelbattle 3.14.1\n" "Report-Msgid-Bugs-To: squirrel-battle@crans.org\n" -"POT-Creation-Date: 2020-11-28 02:50+0100\n" +"POT-Creation-Date: 2020-11-28 16:03+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -37,26 +37,32 @@ msgstr "{name} prend {amount} points de dégât." #: squirrelbattle/menus.py:45 squirrelbattle/tests/translations_test.py:14 #: squirrelbattle/tests/game_test.py:284 squirrelbattle/tests/game_test.py:287 +#: squirrelbattle/tests/translations_test.py:16 msgid "New game" msgstr "Nouvelle partie" #: squirrelbattle/menus.py:46 squirrelbattle/tests/translations_test.py:15 +#: squirrelbattle/tests/translations_test.py:17 msgid "Resume" msgstr "Continuer" #: squirrelbattle/menus.py:47 squirrelbattle/tests/translations_test.py:17 +#: squirrelbattle/tests/translations_test.py:19 msgid "Save" msgstr "Sauvegarder" #: squirrelbattle/menus.py:48 squirrelbattle/tests/translations_test.py:16 +#: squirrelbattle/tests/translations_test.py:18 msgid "Load" msgstr "Charger" #: squirrelbattle/menus.py:49 squirrelbattle/tests/translations_test.py:18 +#: squirrelbattle/tests/translations_test.py:20 msgid "Settings" msgstr "Paramètres" #: squirrelbattle/menus.py:50 squirrelbattle/tests/translations_test.py:19 +#: squirrelbattle/tests/translations_test.py:21 msgid "Exit" msgstr "Quitter" @@ -90,56 +96,67 @@ msgstr "" #: squirrelbattle/settings.py:21 squirrelbattle/tests/translations_test.py:21 #: squirrelbattle/tests/translations_test.py:25 +#: squirrelbattle/tests/translations_test.py:27 msgid "Main key to move up" msgstr "Touche principale pour aller vers le haut" #: squirrelbattle/settings.py:22 squirrelbattle/tests/translations_test.py:23 #: squirrelbattle/tests/translations_test.py:27 +#: squirrelbattle/tests/translations_test.py:29 msgid "Secondary key to move up" msgstr "Touche secondaire pour aller vers le haut" #: squirrelbattle/settings.py:23 squirrelbattle/tests/translations_test.py:25 #: squirrelbattle/tests/translations_test.py:29 +#: squirrelbattle/tests/translations_test.py:31 msgid "Main key to move down" msgstr "Touche principale pour aller vers le bas" #: squirrelbattle/settings.py:24 squirrelbattle/tests/translations_test.py:27 #: squirrelbattle/tests/translations_test.py:31 +#: squirrelbattle/tests/translations_test.py:33 msgid "Secondary key to move down" msgstr "Touche secondaire pour aller vers le bas" #: squirrelbattle/settings.py:25 squirrelbattle/tests/translations_test.py:29 #: squirrelbattle/tests/translations_test.py:33 +#: squirrelbattle/tests/translations_test.py:35 msgid "Main key to move left" msgstr "Touche principale pour aller vers la gauche" #: squirrelbattle/settings.py:26 squirrelbattle/tests/translations_test.py:31 #: squirrelbattle/tests/translations_test.py:35 +#: squirrelbattle/tests/translations_test.py:37 msgid "Secondary key to move left" msgstr "Touche secondaire pour aller vers la gauche" #: squirrelbattle/settings.py:27 squirrelbattle/tests/translations_test.py:33 #: squirrelbattle/tests/translations_test.py:37 +#: squirrelbattle/tests/translations_test.py:39 msgid "Main key to move right" msgstr "Touche principale pour aller vers la droite" #: squirrelbattle/settings.py:29 squirrelbattle/tests/translations_test.py:35 #: squirrelbattle/tests/translations_test.py:39 +#: squirrelbattle/tests/translations_test.py:41 msgid "Secondary key to move right" msgstr "Touche secondaire pour aller vers la droite" #: squirrelbattle/settings.py:30 squirrelbattle/tests/translations_test.py:37 #: squirrelbattle/tests/translations_test.py:41 +#: squirrelbattle/tests/translations_test.py:43 msgid "Key to validate a menu" msgstr "Touche pour valider un menu" #: squirrelbattle/settings.py:31 squirrelbattle/tests/translations_test.py:39 #: squirrelbattle/tests/translations_test.py:43 +#: squirrelbattle/tests/translations_test.py:45 msgid "Texture pack" msgstr "Pack de textures" #: squirrelbattle/settings.py:32 squirrelbattle/tests/translations_test.py:40 #: squirrelbattle/tests/translations_test.py:44 +#: squirrelbattle/tests/translations_test.py:46 msgid "Language" msgstr "Langue" @@ -149,29 +166,36 @@ msgid "{name} dies." msgstr "{name} meurt." #: squirrelbattle/tests/translations_test.py:47 +#: squirrelbattle/tests/translations_test.py:49 msgid "player" msgstr "joueur" #: squirrelbattle/tests/translations_test.py:49 +#: squirrelbattle/tests/translations_test.py:51 msgid "tiger" msgstr "tigre" #: squirrelbattle/tests/translations_test.py:50 +#: squirrelbattle/tests/translations_test.py:52 msgid "hedgehog" msgstr "hérisson" #: squirrelbattle/tests/translations_test.py:51 +#: squirrelbattle/tests/translations_test.py:53 msgid "rabbit" msgstr "lapin" #: squirrelbattle/tests/translations_test.py:52 +#: squirrelbattle/tests/translations_test.py:54 msgid "teddy bear" msgstr "nounours" #: squirrelbattle/tests/translations_test.py:54 +#: squirrelbattle/tests/translations_test.py:56 msgid "bomb" msgstr "bombe" #: squirrelbattle/tests/translations_test.py:55 +#: squirrelbattle/tests/translations_test.py:57 msgid "heart" msgstr "cœur" diff --git a/squirrelbattle/menus.py b/squirrelbattle/menus.py index 1fba7ea..4fcfabe 100644 --- a/squirrelbattle/menus.py +++ b/squirrelbattle/menus.py @@ -98,7 +98,7 @@ class SettingsMenu(Menu): self.update_values(game.settings) elif option == "LOCALE": game.settings.LOCALE = 'fr' if game.settings.LOCALE == 'en'\ - else 'en' + else 'de' if game.settings.LOCALE == 'fr' else 'en' Translator.setlocale(game.settings.LOCALE) game.settings.write_settings() self.update_values(game.settings) diff --git a/squirrelbattle/tests/game_test.py b/squirrelbattle/tests/game_test.py index 9c950d6..a23b6f9 100644 --- a/squirrelbattle/tests/game_test.py +++ b/squirrelbattle/tests/game_test.py @@ -283,6 +283,9 @@ class TestGame(unittest.TestCase): self.assertEqual(self.game.settings.LOCALE, "fr") self.assertEqual(_("New game"), "Nouvelle partie") self.game.handle_key_pressed(KeyValues.ENTER) + self.assertEqual(self.game.settings.LOCALE, "de") + self.assertEqual(_("New game"), "Neu Spiel") + self.game.handle_key_pressed(KeyValues.ENTER) self.assertEqual(self.game.settings.LOCALE, "en") self.assertEqual(_("New game"), "New game") diff --git a/squirrelbattle/translations.py b/squirrelbattle/translations.py index cd5b7fc..f532bb0 100644 --- a/squirrelbattle/translations.py +++ b/squirrelbattle/translations.py @@ -14,7 +14,7 @@ class Translator: Translator.setlocale defines the language of the strings, then gettext() translates the message. """ - SUPPORTED_LOCALES: List[str] = ["en", "fr"] + SUPPORTED_LOCALES: List[str] = ["de", "en", "fr"] locale: str = "en" translators: dict = {}