diff --git a/default_config.json b/default_config.json index fbaae5f5..b4d17cf1 100644 --- a/default_config.json +++ b/default_config.json @@ -8,6 +8,7 @@ "gps_lock": false, "timezone": "America/Los_Angeles" }, + "language": "en", "camera_exp": 400000, "camera_gain": 20, "menu_anim_speed": 0.1, diff --git a/docs/source/dev_guide.rst b/docs/source/dev_guide.rst index 705ee768..43d2fd00 100644 --- a/docs/source/dev_guide.rst +++ b/docs/source/dev_guide.rst @@ -76,6 +76,22 @@ You can then use the supplied ``Makefile`` to build a html tree using ``make htm cd build/html; python -m http.server +Internationalization +----------------------- + +PiFinder uses ``gettext`` and ``pybabel`` for internationalization. +You can find the information in folder ``python/locale`` in the repository. +This means that strings that need translation must be +enclosed in a call to ``_()`` such als ``_("string that needs translation")``. + +As we would like to allow users to switch the language of the user interface from the menu, and with-out restarting PiFinder, +care must be taken, that translations are performed dynamically, i.e. not at load time of python files. +If you have a variable at package level that needs to be translated, you still need to mark the strings with ``_()``, but make sure +it is not translated by overriding the ``_()``-function with a local one, that returns the string and then ``del`` that from the context, when you're done. +You can find an example of this in ``menu_structure.py`` at the top and bottom of the file. + +Please also check your unit tests, that these take care of installing ``_()`` into the local context. (We have not had that case yet.) + Setup the development environment --------------------------------- @@ -190,6 +206,13 @@ The defined sessions are: session is not run by default, but is executed on code check in to the PiFinder repository. +- babel -> Runs the complete toolchain for internationalization (based on `pybabel`). + That means extracts strings to translate and updates the `.po`-files in `python/locale/**` + Then these are compiled into `.mo`-files. Unfortuntely, this changes the `.mo`-files in any case, + even if the there have been no changes to strings or their translation. As this will show up + as changes to checked-in, this is not run by default. + + CI/CD ....... diff --git a/python/PiFinder/main.py b/python/PiFinder/main.py index 7561b76e..7f5103d9 100644 --- a/python/PiFinder/main.py +++ b/python/PiFinder/main.py @@ -10,6 +10,8 @@ """ +import gettext + import os # skyfield performance fix, see: https://rhodesmill.org/skyfield/accuracy-efficiency.html @@ -51,6 +53,12 @@ from PiFinder.calc_utils import sf_utils from PiFinder.displays import DisplayBase, get_display +# Install the _("text") into global context for Internationalization +# On RasPi/Ubuntu the default locale is C.utf8, see `locale -a`, which locales are available +# You need to install `apt install language-pack_xx`, where xx is the ISO country code. +# Passing nothing as third parameter means the language is determined from environment variables (e.g. LANG) +gettext.install("PiFinder", "locale") + logger = logging.getLogger("main") hardware_platform = "Pi" @@ -287,6 +295,13 @@ def main( screen_brightness = cfg.get_option("display_brightness") set_brightness(screen_brightness, cfg) + # Set user interface language + lang = cfg.get_option("language") + langXX = gettext.translation( + "messages", "locale", languages=[lang], fallback=(lang == "en") + ) + langXX.install() + import PiFinder.manager_patch as patch patch.apply() @@ -735,6 +750,10 @@ def rotate_logs() -> Path: return utils.data_dir / "pifinder.log" +############################################################################################# +############################################################################################# +############################################################################################# + if __name__ == "__main__": print("Bootstrap logging configuration ...") logging.basicConfig(format="%(asctime)s BASIC %(name)s: %(levelname)s %(message)s") @@ -816,6 +835,11 @@ def rotate_logs() -> Path: "-x", "--verbose", help="Set logging to debug mode", action="store_true" ) parser.add_argument("-l", "--log", help="Log to file", action="store_true") + parser.add_argument( + "--lang", + help="Force user interface language (iso2 code). Changes configuration", + type=str, + ) args = parser.parse_args() # add the handlers to the logger if args.verbose: @@ -863,7 +887,13 @@ def rotate_logs() -> Path: elif args.keyboard.lower() == "none": from PiFinder import keyboard_none as keyboard # type: ignore[no-redef] - rlogger.warn("using no keyboard") + rlogger.warning("using no keyboard") + + if args.lang: + if args.lang.lower() not in ["en", "de", "fr", "es"]: + raise Exception(f"Unknown language '{args.lang}' passed via command line.") + else: + config.Config().set_option("language", args.lang) # if args.log: # datenow = datetime.datetime.now() diff --git a/python/PiFinder/solver.py b/python/PiFinder/solver.py index 29b01572..c7ebf4b4 100644 --- a/python/PiFinder/solver.py +++ b/python/PiFinder/solver.py @@ -69,11 +69,17 @@ def solver( + shared_state.arch() ) except FileNotFoundError as e: - logger.warn( + logger.warning( "Not using cedar_detect, as corresponding file '%s' could not be found", e.filename, ) cedar_detect = None + except ValueError as e: + logger.warning( + "Not using cedar_detect, as the binary path could not be determined: %s", + e, + ) + cedar_detect = None try: while True: diff --git a/python/PiFinder/ui/align.py b/python/PiFinder/ui/align.py index 7695c8dd..5ace6595 100644 --- a/python/PiFinder/ui/align.py +++ b/python/PiFinder/ui/align.py @@ -53,7 +53,7 @@ def align_on_radec(ra, dec, command_queues, config_object, shared_state) -> bool dec, ] ) - command_queues["console"].put("Align Timeout") + command_queues["console"].put(_("Align Timeout")) return False try: @@ -71,7 +71,7 @@ def align_on_radec(ra, dec, command_queues, config_object, shared_state) -> bool return False # success, set all the things... - command_queues["console"].put("Alignment Set") + command_queues["console"].put(_("Alignment Set")) shared_state.set_solve_pixel(target_pixel) config_object.set_option("solve_pixel", target_pixel) return True @@ -211,13 +211,13 @@ def update(self, force=False): ) self.draw.text( (self.display_class.titlebar_height + 2, 20), - "Can't plot", + _("Can't plot"), font=self.fonts.large.font, fill=self.colors.get(255), ) self.draw.text( (self.display_class.titlebar_height + 2 + self.fonts.large.height, 50), - "No Solve Yet", + _("No Solve Yet"), font=self.fonts.base.font, fill=self.colors.get(255), ) @@ -330,7 +330,7 @@ def key_square(self): self.align_mode = False if self.alignment_star is not None: - self.message("Aligning...", 0.1) + self.message(_("Aligning..."), 0.1) if align_on_radec( self.alignment_star["ra_degrees"], self.alignment_star["dec_degrees"], @@ -338,9 +338,9 @@ def key_square(self): self.config_object, self.shared_state, ): - self.message("Aligned!", 1) + self.message(_("Aligned!"), 1) else: - self.message("Failed", 2) + self.message(_("Alignment failed"), 2) else: self.align_mode = True self.update(force=True) diff --git a/python/PiFinder/ui/base.py b/python/PiFinder/ui/base.py index 592ef83c..b4734dc3 100644 --- a/python/PiFinder/ui/base.py +++ b/python/PiFinder/ui/base.py @@ -17,6 +17,12 @@ from PiFinder.config import Config from PiFinder.ui.marking_menus import MarkingMenu from PiFinder.catalogs import Catalogs +from typing import Any, TYPE_CHECKING + +if TYPE_CHECKING: + + def _(a) -> Any: + return a class UIModule: @@ -191,7 +197,9 @@ def screen_update(self, title_bar=True, button_hints=True) -> None: (6, 1), str(self.fps), font=self.fonts.bold.font, fill=fg ) else: - self.draw.text((6, 1), self.title, font=self.fonts.bold.font, fill=fg) + self.draw.text( + (6, 1), _(self.title), font=self.fonts.bold.font, fill=fg + ) imu = self.shared_state.imu() moving = True if imu and imu["pos"] and imu["moving"] else False diff --git a/python/PiFinder/ui/callbacks.py b/python/PiFinder/ui/callbacks.py index 8fd83d36..b16a85b6 100644 --- a/python/PiFinder/ui/callbacks.py +++ b/python/PiFinder/ui/callbacks.py @@ -10,11 +10,19 @@ import datetime import logging +import gettext +from typing import Any, TYPE_CHECKING from PiFinder import utils from PiFinder.ui.base import UIModule from PiFinder.catalogs import CatalogFilter +if TYPE_CHECKING: + + def _(a) -> Any: + return a + + sys_utils = utils.get_sys_utils() @@ -40,7 +48,7 @@ def reset_filters(ui_module: UIModule) -> None: ui_module.catalogs.set_catalog_filter(new_filter) ui_module.catalogs.filter_catalogs() - ui_module.message("Filters Reset") + ui_module.message(_("Filters Reset")) ui_module.remove_from_stack() return @@ -51,10 +59,10 @@ def activate_debug(ui_module: UIModule) -> None: add fake gps info """ ui_module.command_queues["camera"].put("debug") - ui_module.command_queues["console"].put("Debug: Activated") + ui_module.command_queues["console"].put(_("Debug: Activated")) dt = datetime.datetime(2024, 6, 1, 2, 0, 0) ui_module.shared_state.set_datetime(dt) - ui_module.message("Test Mode") + ui_module.message(_("Test Mode")) def set_exposure(ui_module: UIModule) -> None: @@ -70,7 +78,7 @@ def shutdown(ui_module: UIModule) -> None: """ shuts down the Pi """ - ui_module.message("Shutting Down", 10) + ui_module.message(_("Shutting Down"), 10) sys_utils.shutdown() @@ -79,7 +87,7 @@ def restart_pifinder(ui_module: UIModule) -> None: Uses systemctl to restart the PiFinder service """ - ui_module.message("Restarting...", 2) + ui_module.message(_("Restarting..."), 2) sys_utils.restart_pifinder() @@ -87,24 +95,24 @@ def restart_system(ui_module: UIModule) -> None: """ Restarts the system """ - ui_module.message("Restarting...", 2) + ui_module.message(_("Restarting..."), 2) sys_utils.restart_system() def switch_cam_imx477(ui_module: UIModule) -> None: - ui_module.message("Switching cam", 2) + ui_module.message(_("Switching cam"), 2) sys_utils.switch_cam_imx477() restart_system(ui_module) def switch_cam_imx296(ui_module: UIModule) -> None: - ui_module.message("Switching cam", 2) + ui_module.message(_("Switching cam"), 2) sys_utils.switch_cam_imx296() restart_system(ui_module) def switch_cam_imx462(ui_module: UIModule) -> None: - ui_module.message("Switching cam", 2) + ui_module.message(_("Switching cam"), 2) sys_utils.switch_cam_imx462() restart_system(ui_module) @@ -127,14 +135,25 @@ def get_camera_type(ui_module: UIModule) -> list[str]: return [cam_id] +def switch_language(ui_module: UIModule) -> None: + iso2_code = ui_module.config_object.get_option("language") + msg = str(f"Language: {iso2_code}") + ui_module.message(_(msg)) + lang = gettext.translation( + "messages", "locale", languages=[iso2_code], fallback=(iso2_code == "en") + ) + lang.install() + logger.info("Switch Language: %s", iso2_code) + + def go_wifi_ap(ui_module: UIModule) -> None: - ui_module.message("WiFi to AP", 2) + ui_module.message(_("WiFi to AP"), 2) sys_utils.go_wifi_ap() restart_system(ui_module) def go_wifi_cli(ui_module: UIModule) -> None: - ui_module.message("WiFi to Client", 2) + ui_module.message(_("WiFi to Client"), 2) sys_utils.go_wifi_cli() restart_system(ui_module) diff --git a/python/PiFinder/ui/chart.py b/python/PiFinder/ui/chart.py index 66633d00..76a670dd 100644 --- a/python/PiFinder/ui/chart.py +++ b/python/PiFinder/ui/chart.py @@ -2,7 +2,7 @@ # -*- coding:utf-8 -*- # mypy: ignore-errors """ -This module contains all the UI Module classes +This module contains the chart (starfield + constellation lines) UI Module class """ @@ -202,13 +202,13 @@ def update(self, force=False): ) self.draw.text( (self.display_class.titlebar_height + 2, 20), - "Can't plot", + _("Can't plot"), font=self.fonts.large.font, fill=self.colors.get(255), ) self.draw.text( (self.display_class.titlebar_height + 2 + self.fonts.large.height, 50), - "No Solve Yet", + _("No Solve Yet"), font=self.fonts.base.font, fill=self.colors.get(255), ) diff --git a/python/PiFinder/ui/equipment.py b/python/PiFinder/ui/equipment.py index 9b6c7f85..bd3e3b40 100644 --- a/python/PiFinder/ui/equipment.py +++ b/python/PiFinder/ui/equipment.py @@ -12,6 +12,7 @@ class UIEquipment(UIModule): """ __title__ = "Equipment" + # TODO __help__ for Equipment! def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -31,7 +32,7 @@ def update(self, force=False): if self.config_object.equipment.active_telescope is None: self.draw.text( (10, 20), - "No telescope selected", + _("No telescope selected"), font=self.fonts.small.font, fill=self.colors.get(128), ) @@ -46,7 +47,7 @@ def update(self, force=False): if self.config_object.equipment.active_eyepiece is None: self.draw.text( (10, 35), - "No eyepiece selected", + _("No eyepiece selected"), font=self.fonts.small.font, fill=self.colors.get(128), ) @@ -66,7 +67,7 @@ def update(self, force=False): if mag > 0: self.draw.text( (10, 50), - f"Mag: {mag:.0f}x", + _(f"Mag: {mag:.0f}x"), font=self.fonts.base.font, fill=self.colors.get(128), ) @@ -76,7 +77,7 @@ def update(self, force=False): tfov_minutes = int((tfov - tfov_degrees) * 60) self.draw.text( (10, 70), - f"TFOV: {tfov_degrees:.0f}°{tfov_minutes:02.0f}'", + _(f"TFOV: {tfov_degrees:.0f}°{tfov_minutes:02.0f}'"), font=self.fonts.base.font, fill=self.colors.get(128), ) @@ -85,7 +86,7 @@ def update(self, force=False): self.draw.text( (10, horiz_pos), - "Telescope...", + _("Telescope..."), font=self.fonts.large.font, fill=self.colors.get(192), ) @@ -96,7 +97,7 @@ def update(self, force=False): self.draw.text( (10, horiz_pos), - "Eyepiece...", + _("Eyepiece..."), font=self.fonts.large.font, fill=self.colors.get(192), ) diff --git a/python/PiFinder/ui/log.py b/python/PiFinder/ui/log.py index 3166da9c..a095aca1 100644 --- a/python/PiFinder/ui/log.py +++ b/python/PiFinder/ui/log.py @@ -55,70 +55,72 @@ def __init__(self, *args, **kwargs): # conditions and eyepiece menus self.conditions_menu = { - "name": "Conditions", + "name": _("Conditions"), "class": UITextMenu, "select": "single", "items": [ { - "name": "Transparency", + "name": _("Transparency"), "class": UITextMenu, "select": "single", "config_option": "session.log_transparency", "items": [ { - "name": "NA", + # TRANSLATORS: Transparency not available + "name": _("NA"), "value": "NA", }, { - "name": "Excellent", + "name": _("Excellent"), "value": "Excellent", }, { - "name": "Very Good", + "name": _("Very Good"), "value": "Very Good", }, { - "name": "Good", + "name": _("Good"), "value": "Good", }, { - "name": "Fair", + "name": _("Fair"), "value": "Fair", }, { - "name": "Poor", + "name": _("Poor"), "value": "Poor", }, ], }, { - "name": "Seeing", + "name": _("Seeing"), "class": UITextMenu, "select": "single", "config_option": "session.log_seeing", "items": [ { - "name": "NA", + # TRANSLATORS: Seeing not available + "name": _("NA"), "value": "NA", }, { - "name": "Excellent", + "name": _("Excellent"), "value": "Excellent", }, { - "name": "Very Good", + "name": _("Very Good"), "value": "Very Good", }, { - "name": "Good", + "name": _("Good"), "value": "Good", }, { - "name": "Fair", + "name": _("Fair"), "value": "Fair", }, { - "name": "Poor", + "name": _("Poor"), "value": "Poor", }, ], @@ -169,7 +171,7 @@ def update(self, force=True): if not self.shared_state.solve_state(): self.draw.text( (0, 20), - "No Solve Yet", + _("No Solve Yet"), font=self.fonts.large.font, fill=self.colors.get(255), ) @@ -180,7 +182,7 @@ def update(self, force=True): # Target Name self.draw.text( (10, horiz_pos), - "SAVE Log", + _("SAVE Log"), font=self.fonts.large.font, fill=self.colors.get(255), ) @@ -191,7 +193,7 @@ def update(self, force=True): # Observability self.draw.text( (10, horiz_pos), - "Observability", + _("Observability"), font=self.fonts.large.font, fill=self.colors.get(192), ) @@ -204,7 +206,7 @@ def update(self, force=True): # Appeal self.draw.text( (10, horiz_pos), - "Appeal", + _("Appeal"), font=self.fonts.large.font, fill=self.colors.get(192), ) @@ -216,7 +218,7 @@ def update(self, force=True): self.draw.text( (10, horiz_pos), - "Conditions...", + _("Conditions..."), font=self.fonts.large.font, fill=self.colors.get(192), ) @@ -226,7 +228,7 @@ def update(self, force=True): self.draw.text( (10, horiz_pos), - "Eyepiece...", + _("Eyepiece..."), font=self.fonts.large.font, fill=self.colors.get(192), ) @@ -255,7 +257,8 @@ def record_object(self): # build notes log_eyepiece = self.config_object.equipment.active_eyepiece if log_eyepiece is None: - log_eyepiece = "NA" + # TRANSLATORS: eyepiece info not available + log_eyepiece = _("NA") else: log_eyepiece = f"{log_eyepiece.focal_length_mm}mm {log_eyepiece.name}" @@ -298,7 +301,7 @@ def key_right(self): """ if self.menu_index == 0: self.record_object() - self.message("Logged!") + self.message(_("Logged!")) self.remove_from_stack() return diff --git a/python/PiFinder/ui/menu_structure.py b/python/PiFinder/ui/menu_structure.py index 70954dfc..502e31dd 100644 --- a/python/PiFinder/ui/menu_structure.py +++ b/python/PiFinder/ui/menu_structure.py @@ -10,6 +10,19 @@ from PiFinder.ui.equipment import UIEquipment import PiFinder.ui.callbacks as callbacks + +# override locally the gettext marker function, i.e. the strings are not translated on load, but extracted. +def _(key: str) -> str: + return key + + +s = _("Language: de") # this way ruff lint and mypy type_hints warnings are silenced +s = _("Language: en") +s = _("Language: es") +s = _("Language: fr") +s = s +del s + pifinder_menu = { "name": "PiFinder", "class": UITextMenu, @@ -17,133 +30,133 @@ "start_index": 2, "items": [ { - "name": "Camera", + "name": _("Camera"), "class": UIPreview, }, { - "name": "Align", + "name": _("Align"), "class": UIAlign, "stateful": True, "preload": True, }, { - "name": "Chart", + "name": _("Chart"), "class": UIChart, "stateful": True, "preload": True, }, { - "name": "Objects", + "name": _("Objects"), "class": UITextMenu, "select": "single", "items": [ { - "name": "All Filtered", + "name": _("All Filtered"), "class": UIObjectList, "objects": "catalogs.filtered", }, { - "name": "By Catalog", + "name": _("By Catalog"), "class": UITextMenu, "select": "single", "items": [ { - "name": "Planets", + "name": _("Planets"), "class": UIObjectList, "objects": "catalog", "value": "PL", }, { - "name": "Comets", + "name": _("Comets"), "class": UIObjectList, "objects": "catalog", "value": "CM", }, { - "name": "NGC", + "name": _("NGC"), "class": UIObjectList, "objects": "catalog", "value": "NGC", }, { - "name": "Messier", + "name": _("Messier"), "class": UIObjectList, "objects": "catalog", "value": "M", }, { - "name": "DSO...", + "name": _("DSO..."), "class": UITextMenu, "select": "single", "items": [ { - "name": "Abell Pn", + "name": _("Abell Pn"), "class": UIObjectList, "objects": "catalog", "value": "Abl", }, { - "name": "Arp Galaxies", + "name": _("Arp Galaxies"), "class": UIObjectList, "objects": "catalog", "value": "Arp", }, { - "name": "Barnard", + "name": _("Barnard"), "class": UIObjectList, "objects": "catalog", "value": "B", }, { - "name": "Caldwell", + "name": _("Caldwell"), "class": UIObjectList, "objects": "catalog", "value": "C", }, { - "name": "Collinder", + "name": _("Collinder"), "class": UIObjectList, "objects": "catalog", "value": "Col", }, { - "name": "E.G. Globs", + "name": _("E.G. Globs"), "class": UIObjectList, "objects": "catalog", "value": "EGC", }, { - "name": "Herschel 400", + "name": _("Herschel 400"), "class": UIObjectList, "objects": "catalog", "value": "H", }, { - "name": "IC", + "name": _("IC"), "class": UIObjectList, "objects": "catalog", "value": "IC", }, { - "name": "Messier", + "name": _("Messier"), "class": UIObjectList, "objects": "catalog", "value": "M", }, { - "name": "NGC", + "name": _("NGC"), "class": UIObjectList, "objects": "catalog", "value": "NGC", }, { - "name": "Sharpless", + "name": _("Sharpless"), "class": UIObjectList, "objects": "catalog", "value": "Sh2", }, { - "name": "TAAS 200", + "name": _("TAAS 200"), "class": UIObjectList, "objects": "catalog", "value": "Ta2", @@ -151,42 +164,42 @@ ], }, { - "name": "Stars...", + "name": _("Stars..."), "class": UITextMenu, "select": "single", "items": [ { - "name": "Bright Named", + "name": _("Bright Named"), "class": UIObjectList, "objects": "catalog", "value": "Str", }, { - "name": "SAC Doubles", + "name": _("SAC Doubles"), "class": UIObjectList, "objects": "catalog", "value": "SaM", }, { - "name": "SAC Asterisms", + "name": _("SAC Asterisms"), "class": UIObjectList, "objects": "catalog", "value": "SaA", }, { - "name": "SAC Red Stars", + "name": _("SAC Red Stars"), "class": UIObjectList, "objects": "catalog", "value": "SaR", }, { - "name": "RASC Doubles", + "name": _("RASC Doubles"), "class": UIObjectList, "objects": "catalog", "value": "RDS", }, { - "name": "TLK 90 Variables", + "name": _("TLK 90 Variables"), "class": UIObjectList, "objects": "catalog", "value": "TLK", @@ -196,134 +209,134 @@ ], }, { - "name": "Recent", + "name": _("Recent"), "class": UIObjectList, "objects": "recent", "label": "recent", }, { - "name": "Name Search", + "name": _("Name Search"), "class": UITextEntry, }, ], }, { - "name": "Filter", + "name": _("Filter"), "class": UITextMenu, "select": "single", "label": "filter_options", "items": [ { - "name": "Reset All", + "name": _("Reset All"), "class": UITextMenu, "select": "Single", "items": [ - {"name": "Confirm", "callback": callbacks.reset_filters}, - {"name": "Cancel", "callback": callbacks.go_back}, + {"name": _("Confirm"), "callback": callbacks.reset_filters}, + {"name": _("Cancel"), "callback": callbacks.go_back}, ], }, { - "name": "Catalogs", + "name": _("Catalogs"), "class": UITextMenu, "select": "multi", "config_option": "filter.selected_catalogs", "items": [ { - "name": "Planets", + "name": _("Planets"), "value": "PL", }, { - "name": "NGC", + "name": _("NGC"), "value": "NGC", }, { - "name": "Messier", + "name": _("Messier"), "value": "M", }, { - "name": "DSO...", + "name": _("DSO..."), "class": UITextMenu, "select": "multi", "config_option": "filter.selected_catalogs", "items": [ { - "name": "Abell Pn", + "name": _("Abell Pn"), "value": "Abl", }, { - "name": "Arp Galaxies", + "name": _("Arp Galaxies"), "value": "Arp", }, { - "name": "Barnard", + "name": _("Barnard"), "value": "B", }, { - "name": "Caldwell", + "name": _("Caldwell"), "value": "C", }, { - "name": "Collinder", + "name": _("Collinder"), "value": "Col", }, { - "name": "E.G. Globs", + "name": _("E.G. Globs"), "value": "EGC", }, { - "name": "Herschel 400", + "name": _("Herschel 400"), "value": "H", }, { - "name": "IC", + "name": _("IC"), "value": "IC", }, { - "name": "Messier", + "name": _("Messier"), "value": "M", }, { - "name": "NGC", + "name": _("NGC"), "value": "NGC", }, { - "name": "Sharpless", + "name": _("Sharpless"), "value": "Sh2", }, { - "name": "TAAS 200", + "name": _("TAAS 200"), "value": "Ta2", }, ], }, { - "name": "Stars...", + "name": _("Stars..."), "class": UITextMenu, "select": "multi", "config_option": "filter.selected_catalogs", "items": [ { - "name": "Bright Named", + "name": _("Bright Named"), "value": "Str", }, { - "name": "SAC Doubles", + "name": _("SAC Doubles"), "value": "SaM", }, { - "name": "SAC Asterisms", + "name": _("SAC Asterisms"), "value": "SaA", }, { - "name": "SAC Red Stars", + "name": _("SAC Red Stars"), "value": "SaR", }, { - "name": "RASC Doubles", + "name": _("RASC Doubles"), "value": "RDS", }, { - "name": "TLK 90 Variables", + "name": _("TLK 90 Variables"), "value": "TLK", }, ], @@ -331,77 +344,77 @@ ], }, { - "name": "Type", + "name": _("Type"), "class": UITextMenu, "select": "multi", "config_option": "filter.object_types", "items": [ { - "name": "Galaxy", + "name": _("Galaxy"), "value": "Gx", }, { - "name": "Open Cluster", + "name": _("Open Cluster"), "value": "OC", }, { - "name": "Cluster/Neb", + "name": _("Cluster/Neb"), "value": "C+N", }, { - "name": "Globular", + "name": _("Globular"), "value": "Gb", }, { - "name": "Nebula", + "name": _("Nebula"), "value": "Nb", }, { - "name": "P. Nebula", + "name": _("P. Nebula"), "value": "PN", }, { - "name": "Dark Nebula", + "name": _("Dark Nebula"), "value": "DN", }, { - "name": "Star", + "name": _("Star"), "value": "*", }, { - "name": "Double Str", + "name": _("Double Str"), "value": "D*", }, { - "name": "Triple Str", + "name": _("Triple Str"), "value": "***", }, { - "name": "Knot", + "name": _("Knot"), "value": "Kt", }, { - "name": "Asterism", + "name": _("Asterism"), "value": "Ast", }, { - "name": "Planet", + "name": _("Planet"), "value": "Pla", }, { - "name": "Comet", + "name": _("Comet"), "value": "CM", }, ], }, { - "name": "Altitude", + "name": _("Altitude"), "class": UITextMenu, "select": "single", "config_option": "filter.altitude", "items": [ { - "name": "None", + "name": _("None"), "value": -1, }, { @@ -427,13 +440,13 @@ ], }, { - "name": "Magnitude", + "name": _("Magnitude"), "class": UITextMenu, "select": "single", "config_option": "filter.magnitude", "items": [ { - "name": "None", + "name": _("None"), "value": -1, }, { @@ -479,21 +492,21 @@ ], }, { - "name": "Observed", + "name": _("Observed"), "class": UITextMenu, "select": "single", "config_option": "filter.observed", "items": [ { - "name": "Any", + "name": _("Any"), "value": "Any", }, { - "name": "Observed", + "name": _("Observed"), "value": "Yes", }, { - "name": "Not Observed", + "name": _("Not Observed"), "value": "No", }, ], @@ -501,17 +514,17 @@ ], }, { - "name": "Settings", + "name": _("Settings"), "class": UITextMenu, "select": "single", "items": [ { - "name": "User Pref...", + "name": _("User Pref..."), "class": UITextMenu, "select": "single", "items": [ { - "name": "Key Bright", + "name": _("Key Bright"), "class": UITextMenu, "select": "single", "config_option": "keypad_brightness", @@ -551,13 +564,13 @@ ], }, { - "name": "Sleep Time", + "name": _("Sleep Time"), "class": UITextMenu, "select": "single", "config_option": "sleep_timeout", "items": [ { - "name": "Off", + "name": _("Off"), "value": "Off", }, { @@ -583,66 +596,66 @@ ], }, { - "name": "Menu Anim", + "name": _("Menu Anim"), "class": UITextMenu, "select": "single", "config_option": "menu_anim_speed", "items": [ { - "name": "Off", + "name": _("Off"), "value": 0, }, { - "name": "Fast", + "name": _("Fast"), "value": 0.05, }, { - "name": "Medium", + "name": _("Medium"), "value": 0.1, }, { - "name": "Slow", + "name": _("Slow"), "value": 0.2, }, ], }, { - "name": "Scroll Speed", + "name": _("Scroll Speed"), "class": UITextMenu, "select": "single", "config_option": "text_scroll_speed", "items": [ { - "name": "Off", + "name": _("Off"), "value": "Off", }, { - "name": "Fast", + "name": _("Fast"), "value": "Fast", }, { - "name": "Medium", + "name": _("Medium"), "value": "Med", }, { - "name": "Slow", + "name": _("Slow"), "value": "Slow", }, ], }, { - "name": "Az Arrows", + "name": _("Az Arrows"), "class": UITextMenu, "select": "single", "config_option": "pushto_az_arrows", "label": "pushto_az_arrows", "items": [ { - "name": "Default", + "name": _("Default"), "value": "Default", }, { - "name": "Reverse", + "name": _("Reverse"), "value": "Reverse", }, ], @@ -650,99 +663,99 @@ ], }, { - "name": "Chart...", + "name": _("Chart..."), "class": UITextMenu, "select": "single", "label": "chart_settings", "items": [ { - "name": "Reticle", + "name": _("Reticle"), "class": UITextMenu, "select": "single", "config_option": "chart_reticle", "items": [ { - "name": "Off", + "name": _("Off"), "value": 0, }, { - "name": "Low", + "name": _("Low"), "value": 64, }, { - "name": "Medium", + "name": _("Medium"), "value": 128, }, { - "name": "High", + "name": _("High"), "value": 192, }, ], }, { - "name": "Constellation", + "name": _("Constellation"), "class": UITextMenu, "select": "single", "config_option": "chart_constellations", "items": [ { - "name": "Off", + "name": _("Off"), "value": 0, }, { - "name": "Low", + "name": _("Low"), "value": 64, }, { - "name": "Medium", + "name": _("Medium"), "value": 128, }, { - "name": "High", + "name": _("High"), "value": 192, }, ], }, { - "name": "DSO Display", + "name": _("DSO Display"), "class": UITextMenu, "select": "single", "config_option": "chart_dso", "items": [ { - "name": "Off", + "name": _("Off"), "value": 0, }, { - "name": "Low", + "name": _("Low"), "value": 64, }, { - "name": "Medium", + "name": _("Medium"), "value": 128, }, { - "name": "High", + "name": _("High"), "value": 192, }, ], }, { - "name": "RA/DEC Disp.", + "name": _("RA/DEC Disp."), "class": UITextMenu, "select": "single", "config_option": "chart_radec", "items": [ { - "name": "Off", + "name": _("Off"), "value": "Off", }, { - "name": "HH:MM", + "name": _("HH:MM"), "value": "HH:MM", }, { - "name": "Degrees", + "name": _("Degrees"), "value": "Degr", }, ], @@ -750,7 +763,7 @@ ], }, { - "name": "Camera Exp", + "name": _("Camera Exp"), "class": UITextMenu, "select": "single", "config_option": "camera_exp", @@ -758,37 +771,37 @@ "post_callback": callbacks.set_exposure, "items": [ { - "name": "0.025s", + "name": _("0.025s"), "value": 25000, }, { - "name": "0.05s", + "name": _("0.05s"), "value": 50000, }, { - "name": "0.1s", + "name": _("0.1s"), "value": 100000, }, { - "name": "0.2s", + "name": _("0.2s"), "value": 200000, }, { - "name": "0.4s", + "name": _("0.4s"), "value": 400000, }, { - "name": "0.8s", + "name": _("0.8s"), "value": 800000, }, { - "name": "1s", + "name": _("1s"), "value": 1000000, }, ], }, { - "name": "WiFi Mode", + "name": _("WiFi Mode"), "class": UITextMenu, "select": "single", "value_callback": callbacks.get_wifi_mode, @@ -806,69 +819,69 @@ ], }, { - "name": "PiFinder Type", + "name": _("PiFinder Type"), "class": UITextMenu, "select": "single", "config_option": "screen_direction", "post_callback": callbacks.restart_pifinder, "items": [ { - "name": "Left", + "name": _("Left"), "value": "left", }, { - "name": "Right", + "name": _("Right"), "value": "right", }, { - "name": "Straight", + "name": _("Straight"), "value": "straight", }, { - "name": "Flat v3", + "name": _("Flat v3"), "value": "flat3", }, { - "name": "Flat v2", + "name": _("Flat v2"), "value": "flat", }, ], }, { - "name": "Mount Type", + "name": _("Mount Type"), "class": UITextMenu, "select": "single", "config_option": "mount_type", "post_callback": callbacks.restart_pifinder, "items": [ { - "name": "Alt/Az", + "name": _("Alt/Az"), "value": "Alt/Az", }, { - "name": "Equitorial", + "name": _("Equitorial"), "value": "EQ", }, ], }, { - "name": "Camera Type", + "name": _("Camera Type"), "class": UITextMenu, "select": "single", "value_callback": callbacks.get_camera_type, "items": [ { - "name": "v2 - imx477", + "name": _("v2 - imx477"), "callback": callbacks.switch_cam_imx477, "value": "imx477", }, { - "name": "v3 - imx296", + "name": _("v3 - imx296"), "callback": callbacks.switch_cam_imx296, "value": "imx296", }, { - "name": "v3 - imx462", + "name": _("v3 - imx462"), "callback": callbacks.switch_cam_imx462, "value": "imx462", }, @@ -877,23 +890,23 @@ ], }, { - "name": "Tools", + "name": _("Tools"), "class": UITextMenu, "select": "single", "items": [ - {"name": "Status", "class": UIStatus}, - {"name": "Equipment", "class": UIEquipment, "label": "equipment"}, - {"name": "Console", "class": UIConsole}, - {"name": "Software Upd", "class": UISoftware}, - {"name": "Test Mode", "callback": callbacks.activate_debug}, + {"name": _("Status"), "class": UIStatus}, + {"name": _("Equipment"), "class": UIEquipment, "label": "equipment"}, + {"name": _("Console"), "class": UIConsole}, + {"name": _("Software Upd"), "class": UISoftware}, + {"name": _("Test Mode"), "callback": callbacks.activate_debug}, { - "name": "Power", + "name": _("Power"), "class": UITextMenu, "select": "Single", "label": "power", "items": [ { - "name": "Shutdown", + "name": _("Shutdown"), "class": UITextMenu, "select": "Single", "label": "shutdown", @@ -903,16 +916,48 @@ ], }, { - "name": "Restart", + "name": _("Restart"), "class": UITextMenu, "select": "Single", "label": "restart", "items": [ { - "name": "Confirm", + "name": _("Confirm"), "callback": callbacks.restart_system, }, - {"name": "Cancel", "callback": callbacks.go_back}, + {"name": _("Cancel"), "callback": callbacks.go_back}, + ], + }, + ], + }, + { + "name": _("Experimental"), + "class": UITextMenu, + "select": "Single", + "items": [ + { + "name": _("Language"), + "class": UITextMenu, + "select": "single", + "config_option": "language", + "post_callback": callbacks.switch_language, + "items": [ + { + "name": _("English"), + "value": "en", + }, + { + "name": _("German"), + "value": "de", + }, + { + "name": _("French"), + "value": "fr", + }, + { + "name": _("Spanish"), + "value": "es", + }, ], }, ], @@ -921,3 +966,7 @@ }, ], } + + +# Remove local definition and reactivate the global gettext function (that translates) +del _ diff --git a/python/PiFinder/ui/object_details.py b/python/PiFinder/ui/object_details.py index 7cc92920..4b05fc76 100644 --- a/python/PiFinder/ui/object_details.py +++ b/python/PiFinder/ui/object_details.py @@ -2,7 +2,7 @@ # -*- coding:utf-8 -*- # mypy: ignore-errors """ -This module contains all the UI Module classes +This module contains all the UI code for the object details screen """ @@ -256,13 +256,13 @@ def _render_pointing_instructions(self): else: self.draw.text( (10, 70), - "Searching", + _("Searching"), font=self.fonts.large.font, fill=self.colors.get(255), ) self.draw.text( (10, 90), - f"for GPS{'.' * int(self._elipsis_count / 10)}", + _(f"for GPS{'.' * int(self._elipsis_count / 10)}"), font=self.fonts.large.font, fill=self.colors.get(255), ) @@ -272,13 +272,13 @@ def _render_pointing_instructions(self): elif not self._check_catalog_initialised(): self.draw.text( (10, 70), - "Calculating", + _("Calculating"), font=self.fonts.large.font, fill=self.colors.get(255), ) self.draw.text( (10, 90), - f"positions{'.' * int(self._elipsis_count / 10)}", + _(f"positions{'.' * int(self._elipsis_count / 10)}"), font=self.fonts.large.font, fill=self.colors.get(255), ) @@ -441,7 +441,7 @@ def mm_align(self, _marking_menu, _menu_item) -> bool: """ Called from marking menu to align on curent object """ - self.message("Aligning...", 0.1) + self.message(_("Aligning..."), 0.1) if align_on_radec( self.object.ra, self.object.dec, @@ -449,9 +449,9 @@ def mm_align(self, _marking_menu, _menu_item) -> bool: self.config_object, self.shared_state, ): - self.message("Aligned!", 1) + self.message(_("Aligned!"), 1) else: - self.message("Too Far", 2) + self.message(_("Too Far"), 2) return True diff --git a/python/PiFinder/ui/object_list.py b/python/PiFinder/ui/object_list.py index 5a777c01..02d53834 100644 --- a/python/PiFinder/ui/object_list.py +++ b/python/PiFinder/ui/object_list.py @@ -30,7 +30,12 @@ TextLayouterScroll, name_deduplicate, ) +from typing import Any, TYPE_CHECKING +if TYPE_CHECKING: + + def _(a) -> Any: + return a class DisplayModes(Enum): """ @@ -183,13 +188,15 @@ def refresh_object_list(self, force_update=False): self.sort() def sort(self) -> None: - message = f"Sorting by\n{'number' if self.current_sort == SortOrder.CATALOG_SEQUENCE else 'nearby'}" + message = _( + f"Sorting by\n{'number' if self.current_sort == SortOrder.CATALOG_SEQUENCE else 'nearby'}" + ) self.message(message, 0.1) self.update() if self.current_sort == SortOrder.NEAREST: if self.shared_state.solution() is None: - self.message("No Solve Yet", 1) + self.message(_("No Solve Yet"), 1) self.current_sort = SortOrder.CATALOG_SEQUENCE else: if self.catalogs.catalog_filter: @@ -209,7 +216,7 @@ def nearby_refresh(self): self._menu_items_sorted = self.nearby.refresh() if self._menu_items_sorted is None: self._menu_items_sorted = self._menu_items - self.message("No Solve Yet", 1) + self.message(_("No Solve Yet"), 1) def format_az_alt(self, point_az, point_alt): if point_az >= 0: @@ -392,13 +399,13 @@ def update(self, force: bool = False) -> None: if self.get_nr_of_menu_items() == 0: self.draw.text( (begin_x, self.line_position(2)), - "No objects", + _("No objects"), font=self.fonts.bold.font, fill=self.colors.get(255), ) self.draw.text( (begin_x, self.line_position(3)), - "match filter", + _("match filter"), font=self.fonts.bold.font, fill=self.colors.get(255), ) @@ -414,13 +421,17 @@ def update(self, force: bool = False) -> None: intensity: int = int(64 + ((2.0 - self._current_item_index) * 32.0)) self.draw.text( (begin_x, self.line_position(0)), - f"{self.catalog_info_1} obj{f', {self.catalog_info_2}d old' if self.catalog_info_2 else ''}", + _( + f"{self.catalog_info_1} obj{f', {self.catalog_info_2}d old' if self.catalog_info_2 else ''}" + ), font=self.fonts.bold.font, fill=self.colors.get(intensity), ) self.draw.text( (begin_x, self.line_position(1)), - f"Sort: {'Catalog' if self.current_sort == SortOrder.CATALOG_SEQUENCE else 'Nearby'}", + _( + f"Sort: {'Catalog' if self.current_sort == SortOrder.CATALOG_SEQUENCE else 'Nearby'}" + ), font=self.fonts.bold.font, fill=self.colors.get(intensity), ) diff --git a/python/PiFinder/ui/preview.py b/python/PiFinder/ui/preview.py index e93fce91..d65c3e3b 100644 --- a/python/PiFinder/ui/preview.py +++ b/python/PiFinder/ui/preview.py @@ -1,7 +1,7 @@ #!/usr/bin/python # -*- coding:utf-8 -*- """ -This module contains all the UI Module classes +This module contains the UI Preview class """ diff --git a/python/PiFinder/ui/software.py b/python/PiFinder/ui/software.py index ad650e5f..f5171d54 100644 --- a/python/PiFinder/ui/software.py +++ b/python/PiFinder/ui/software.py @@ -85,12 +85,12 @@ def get_release_version(self): self._release_version = "Unknown" def update_software(self): - self.message("Updating...", 10) + self.message(_("Updating..."), 10) if sys_utils.update_software(): - self.message("Ok! Restarting", 10) + self.message(_("Ok! Restarting"), 10) sys_utils.restart_system() else: - self.message("Error on Upd", 3) + self.message(_("Error on Upd"), 3) def update(self, force=False): time.sleep(1 / 30) @@ -98,7 +98,7 @@ def update(self, force=False): draw_pos = self.display_class.titlebar_height + 2 self.draw.text( (0, draw_pos), - f"Wifi Mode: {self._wifi_mode}", + _(f"Wifi Mode: {self._wifi_mode}"), font=self.fonts.base.font, fill=self.colors.get(128), ) @@ -106,7 +106,7 @@ def update(self, force=False): self.draw.text( (0, draw_pos), - "Current Version", + _("Current Version"), font=self.fonts.bold.font, fill=self.colors.get(128), ) @@ -122,7 +122,7 @@ def update(self, force=False): self.draw.text( (0, draw_pos), - "Release Version", + _("Release Version"), font=self.fonts.bold.font, fill=self.colors.get(128), ) @@ -138,13 +138,13 @@ def update(self, force=False): if self._wifi_mode != "Client": self.draw.text( (10, 90), - "WiFi must be", + _("WiFi must be"), font=self.fonts.large.font, fill=self.colors.get(255), ) self.draw.text( (10, 105), - "client mode", + _("client mode"), font=self.fonts.large.font, fill=self.colors.get(255), ) @@ -157,13 +157,13 @@ def update(self, force=False): self.get_release_version() self.draw.text( (10, 90), - "Checking for", + _("Checking for"), font=self.fonts.large.font, fill=self.colors.get(255), ) self.draw.text( (10, 105), - f"updates{'.' * int(self._elipsis_count / 10)}", + _(f"updates{'.' * int(self._elipsis_count / 10)}"), font=self.fonts.large.font, fill=self.colors.get(255), ) @@ -177,13 +177,13 @@ def update(self, force=False): ): self.draw.text( (10, 90), - "No Update", + _("No Update"), font=self.fonts.large.font, fill=self.colors.get(255), ) self.draw.text( (10, 105), - "needed", + _("needed"), font=self.fonts.large.font, fill=self.colors.get(255), ) @@ -193,13 +193,13 @@ def update(self, force=False): self._go_for_update = True self.draw.text( (10, 90), - "Update Now", + _("Update Now"), font=self.fonts.large.font, fill=self.colors.get(255), ) self.draw.text( (10, 105), - "Cancel", + _("Cancel"), font=self.fonts.large.font, fill=self.colors.get(255), ) diff --git a/python/PiFinder/ui/status.py b/python/PiFinder/ui/status.py index 5b808036..1654201b 100644 --- a/python/PiFinder/ui/status.py +++ b/python/PiFinder/ui/status.py @@ -1,7 +1,7 @@ #!/usr/bin/python # -*- coding:utf-8 -*- """ -This module contains all the UI Module classes +This module contains the UI Status class """ diff --git a/python/PiFinder/ui/text_menu.py b/python/PiFinder/ui/text_menu.py index f6805e96..fa37b64b 100644 --- a/python/PiFinder/ui/text_menu.py +++ b/python/PiFinder/ui/text_menu.py @@ -114,7 +114,7 @@ def update(self, force=False): self.draw.text( (line_horiz_pos, line_pos), - item_text, + _(item_text), font=line_font.font, fill=self.colors.get(line_color), ) diff --git a/python/PiFinder/ui/textentry.py b/python/PiFinder/ui/textentry.py index c40f9eb8..0f06a934 100644 --- a/python/PiFinder/ui/textentry.py +++ b/python/PiFinder/ui/textentry.py @@ -4,6 +4,12 @@ from PiFinder.ui.object_list import UIObjectList from PiFinder.ui.ui_utils import format_number import time +from typing import Any, TYPE_CHECKING + +if TYPE_CHECKING: + + def _(a) -> Any: + return a # class CompositeObjectBuilder: # diff --git a/python/locale/de/LC_MESSAGES/messages.mo b/python/locale/de/LC_MESSAGES/messages.mo new file mode 100644 index 00000000..eecbb7d3 Binary files /dev/null and b/python/locale/de/LC_MESSAGES/messages.mo differ diff --git a/python/locale/de/LC_MESSAGES/messages.po b/python/locale/de/LC_MESSAGES/messages.po new file mode 100644 index 00000000..236e6681 --- /dev/null +++ b/python/locale/de/LC_MESSAGES/messages.po @@ -0,0 +1,703 @@ +# German (Germany) translations for PiFinder. +# Copyright (C) 2025 ORGANIZATION +# This file is distributed under the same license as the PiFinder project. +# Grimaldi, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2025-02-09 18:27+0100\n" +"PO-Revision-Date: 2025-01-12 18:13+0100\n" +"Last-Translator: Jens Scheidtmann\n" +"Language: de_DE\n" +"Language-Team: de_DE \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.16.0\n" + +#: PiFinder/ui/align.py:56 +msgid "Align Timeout" +msgstr "Justage Timeout" + +#: PiFinder/ui/align.py:74 +msgid "Alignment Set" +msgstr "Justage fertig" + +#: PiFinder/ui/align.py:214 PiFinder/ui/chart.py:205 +msgid "Can't plot" +msgstr "keine Just." + +#: PiFinder/ui/align.py:220 PiFinder/ui/chart.py:211 PiFinder/ui/log.py:174 +#: PiFinder/ui/object_list.py:199 PiFinder/ui/object_list.py:219 +msgid "No Solve Yet" +msgstr "ohne Position" + +#: PiFinder/ui/align.py:333 PiFinder/ui/object_details.py:444 +msgid "Aligning..." +msgstr "Justage..." + +#: PiFinder/ui/align.py:341 PiFinder/ui/object_details.py:452 +msgid "Aligned!" +msgstr "Justiert!" + +#: PiFinder/ui/align.py:343 +msgid "Alignment failed" +msgstr "Justage abgebrochen" + +#: PiFinder/ui/callbacks.py:51 +msgid "Filters Reset" +msgstr "Filterreset" + +#: PiFinder/ui/callbacks.py:62 +msgid "Debug: Activated" +msgstr "Debug: Aktiviert" + +#: PiFinder/ui/callbacks.py:65 PiFinder/ui/menu_structure.py:901 +msgid "Test Mode" +msgstr "Test Modus" + +#: PiFinder/ui/callbacks.py:81 +msgid "Shutting Down" +msgstr "Ausschalten" + +#: PiFinder/ui/callbacks.py:90 PiFinder/ui/callbacks.py:98 +msgid "Restarting..." +msgstr "Neustart..." + +#: PiFinder/ui/callbacks.py:103 PiFinder/ui/callbacks.py:109 +#: PiFinder/ui/callbacks.py:115 +msgid "Switching cam" +msgstr "andere Kamera" + +#: PiFinder/ui/callbacks.py:150 +msgid "WiFi to AP" +msgstr "WLAN AP" + +#: PiFinder/ui/callbacks.py:156 +msgid "WiFi to Client" +msgstr "WLAN Client" + +#: PiFinder/ui/equipment.py:35 +msgid "No telescope selected" +msgstr "Kein Teleskop gewählt" + +#: PiFinder/ui/equipment.py:50 +msgid "No eyepiece selected" +msgstr "Kein Okular gewählt" + +#: PiFinder/ui/equipment.py:89 +msgid "Telescope..." +msgstr "Teleskope..." + +#: PiFinder/ui/equipment.py:100 PiFinder/ui/log.py:231 +msgid "Eyepiece..." +msgstr "Okulare..." + +#: PiFinder/ui/log.py:58 +msgid "Conditions" +msgstr "Bedingungen" + +#: PiFinder/ui/log.py:63 +msgid "Transparency" +msgstr "Transparenz" + +#. TRANSLATORS: Transparency not available +#. TRANSLATORS: Seeing not available +#. TRANSLATORS: eyepiece info not available +#: PiFinder/ui/log.py:70 PiFinder/ui/log.py:103 PiFinder/ui/log.py:261 +msgid "NA" +msgstr "Nicht eingetragen" + +#: PiFinder/ui/log.py:74 PiFinder/ui/log.py:107 +msgid "Excellent" +msgstr "Exzellent" + +#: PiFinder/ui/log.py:78 PiFinder/ui/log.py:111 +msgid "Very Good" +msgstr "Sehr gut" + +#: PiFinder/ui/log.py:82 PiFinder/ui/log.py:115 +msgid "Good" +msgstr "Gut" + +#: PiFinder/ui/log.py:86 PiFinder/ui/log.py:119 +msgid "Fair" +msgstr "Okay" + +#: PiFinder/ui/log.py:90 PiFinder/ui/log.py:123 +msgid "Poor" +msgstr "Schlecht" + +#: PiFinder/ui/log.py:96 +msgid "Seeing" +msgstr "Seeing" + +#: PiFinder/ui/log.py:185 +msgid "SAVE Log" +msgstr "Log speichern" + +#: PiFinder/ui/log.py:196 +msgid "Observability" +msgstr "Beobachtbarkeita" + +#: PiFinder/ui/log.py:209 +msgid "Appeal" +msgstr "Eindruck" + +#: PiFinder/ui/log.py:221 +msgid "Conditions..." +msgstr "Bedingungen..." + +#: PiFinder/ui/log.py:304 +msgid "Logged!" +msgstr "Geloggt!" + +#: PiFinder/ui/menu_structure.py:19 +msgid "Language: de" +msgstr "Sprache: Deutsch" + +#: PiFinder/ui/menu_structure.py:20 +msgid "Language: en" +msgstr "Sprache: Englisch" + +#: PiFinder/ui/menu_structure.py:21 +msgid "Language: es" +msgstr "Sprache: Spanisch" + +#: PiFinder/ui/menu_structure.py:22 +msgid "Language: fr" +msgstr "Sprache: Französisch" + +#: PiFinder/ui/menu_structure.py:33 +msgid "Camera" +msgstr "Kamera" + +#: PiFinder/ui/menu_structure.py:37 +msgid "Align" +msgstr "Justage" + +#: PiFinder/ui/menu_structure.py:43 +msgid "Chart" +msgstr "Karte" + +#: PiFinder/ui/menu_structure.py:49 +msgid "Objects" +msgstr "Objekte" + +#: PiFinder/ui/menu_structure.py:54 +msgid "All Filtered" +msgstr "Gefiltr Obj" + +#: PiFinder/ui/menu_structure.py:59 +msgid "By Catalog" +msgstr "nach Katalog" + +#: PiFinder/ui/menu_structure.py:64 PiFinder/ui/menu_structure.py:245 +msgid "Planets" +msgstr "Planeten" + +#: PiFinder/ui/menu_structure.py:70 +msgid "Comets" +msgstr "Kometen" + +#: PiFinder/ui/menu_structure.py:76 PiFinder/ui/menu_structure.py:147 +#: PiFinder/ui/menu_structure.py:249 PiFinder/ui/menu_structure.py:299 +msgid "NGC" +msgstr "NGC" + +#: PiFinder/ui/menu_structure.py:82 PiFinder/ui/menu_structure.py:141 +#: PiFinder/ui/menu_structure.py:253 PiFinder/ui/menu_structure.py:295 +msgid "Messier" +msgstr "Messier" + +#: PiFinder/ui/menu_structure.py:88 PiFinder/ui/menu_structure.py:257 +msgid "DSO..." +msgstr "DSO..." + +#: PiFinder/ui/menu_structure.py:93 PiFinder/ui/menu_structure.py:263 +msgid "Abell Pn" +msgstr "Abell PN" + +#: PiFinder/ui/menu_structure.py:99 PiFinder/ui/menu_structure.py:267 +msgid "Arp Galaxies" +msgstr "Arp Galaxien" + +#: PiFinder/ui/menu_structure.py:105 PiFinder/ui/menu_structure.py:271 +msgid "Barnard" +msgstr "Barnard" + +#: PiFinder/ui/menu_structure.py:111 PiFinder/ui/menu_structure.py:275 +msgid "Caldwell" +msgstr "Caldwell" + +#: PiFinder/ui/menu_structure.py:117 PiFinder/ui/menu_structure.py:279 +msgid "Collinder" +msgstr "Collinger" + +#: PiFinder/ui/menu_structure.py:123 PiFinder/ui/menu_structure.py:283 +msgid "E.G. Globs" +msgstr "E.G. Globs" + +#: PiFinder/ui/menu_structure.py:129 PiFinder/ui/menu_structure.py:287 +msgid "Herschel 400" +msgstr "Herschel 400" + +#: PiFinder/ui/menu_structure.py:135 PiFinder/ui/menu_structure.py:291 +msgid "IC" +msgstr "IC" + +#: PiFinder/ui/menu_structure.py:153 PiFinder/ui/menu_structure.py:303 +msgid "Sharpless" +msgstr "Sharpless" + +#: PiFinder/ui/menu_structure.py:159 PiFinder/ui/menu_structure.py:307 +msgid "TAAS 200" +msgstr "TAAS 200" + +#: PiFinder/ui/menu_structure.py:167 PiFinder/ui/menu_structure.py:313 +msgid "Stars..." +msgstr "Sterne..." + +#: PiFinder/ui/menu_structure.py:172 PiFinder/ui/menu_structure.py:319 +msgid "Bright Named" +msgstr "Bright-Star" + +#: PiFinder/ui/menu_structure.py:178 PiFinder/ui/menu_structure.py:323 +msgid "SAC Doubles" +msgstr "SAC Doppel" + +#: PiFinder/ui/menu_structure.py:184 PiFinder/ui/menu_structure.py:327 +msgid "SAC Asterisms" +msgstr "SAC Asterismen" + +#: PiFinder/ui/menu_structure.py:190 PiFinder/ui/menu_structure.py:331 +msgid "SAC Red Stars" +msgstr "SAC Rote Riesen" + +#: PiFinder/ui/menu_structure.py:196 PiFinder/ui/menu_structure.py:335 +msgid "RASC Doubles" +msgstr "RASC Doppel" + +#: PiFinder/ui/menu_structure.py:202 PiFinder/ui/menu_structure.py:339 +msgid "TLK 90 Variables" +msgstr "TLK 90 Variable" + +#: PiFinder/ui/menu_structure.py:212 +msgid "Recent" +msgstr "Zuletzt" + +#: PiFinder/ui/menu_structure.py:218 +msgid "Name Search" +msgstr "Namenssuche" + +#: PiFinder/ui/menu_structure.py:224 +msgid "Filter" +msgstr "Filter" + +#: PiFinder/ui/menu_structure.py:230 +msgid "Reset All" +msgstr "Zurücksetzen" + +#: PiFinder/ui/menu_structure.py:234 PiFinder/ui/menu_structure.py:925 +msgid "Confirm" +msgstr "Bestätigen" + +#: PiFinder/ui/menu_structure.py:235 PiFinder/ui/menu_structure.py:928 +#: PiFinder/ui/software.py:202 +msgid "Cancel" +msgstr "Abbrechen" + +#: PiFinder/ui/menu_structure.py:239 +msgid "Catalogs" +msgstr "Kataloge" + +#: PiFinder/ui/menu_structure.py:347 +msgid "Type" +msgstr "Typ" + +#: PiFinder/ui/menu_structure.py:353 +msgid "Galaxy" +msgstr "Galaxie" + +#: PiFinder/ui/menu_structure.py:357 +msgid "Open Cluster" +msgstr "Offene Haufen" + +#: PiFinder/ui/menu_structure.py:361 +msgid "Cluster/Neb" +msgstr "Offene Haufen/Nebel" + +#: PiFinder/ui/menu_structure.py:365 +msgid "Globular" +msgstr "Kugelsternhaufen" + +#: PiFinder/ui/menu_structure.py:369 +msgid "Nebula" +msgstr "Nebel" + +#: PiFinder/ui/menu_structure.py:373 +msgid "P. Nebula" +msgstr "Plan. Nebel" + +#: PiFinder/ui/menu_structure.py:377 +msgid "Dark Nebula" +msgstr "Dunkelnebel" + +#: PiFinder/ui/menu_structure.py:381 +msgid "Star" +msgstr "Stern" + +#: PiFinder/ui/menu_structure.py:385 +msgid "Double Str" +msgstr "Doppel Strn" + +#: PiFinder/ui/menu_structure.py:389 +msgid "Triple Str" +msgstr "Dreif. Strn" + +#: PiFinder/ui/menu_structure.py:393 +msgid "Knot" +msgstr "Knoten" + +#: PiFinder/ui/menu_structure.py:397 +msgid "Asterism" +msgstr "Asterismus" + +#: PiFinder/ui/menu_structure.py:401 +msgid "Planet" +msgstr "Planet" + +#: PiFinder/ui/menu_structure.py:405 +msgid "Comet" +msgstr "Komet" + +#: PiFinder/ui/menu_structure.py:411 +msgid "Altitude" +msgstr "Höhe" + +#: PiFinder/ui/menu_structure.py:417 PiFinder/ui/menu_structure.py:449 +msgid "None" +msgstr "Nix" + +#: PiFinder/ui/menu_structure.py:443 +msgid "Magnitude" +msgstr "Magnitude" + +#: PiFinder/ui/menu_structure.py:495 PiFinder/ui/menu_structure.py:505 +msgid "Observed" +msgstr "beobachtet" + +#: PiFinder/ui/menu_structure.py:501 +msgid "Any" +msgstr "Alle" + +#: PiFinder/ui/menu_structure.py:509 +msgid "Not Observed" +msgstr "nicht beobachtet" + +#: PiFinder/ui/menu_structure.py:517 +msgid "Settings" +msgstr "Einstellungen" + +#: PiFinder/ui/menu_structure.py:522 +msgid "User Pref..." +msgstr "Nutzer..." + +#: PiFinder/ui/menu_structure.py:527 +msgid "Key Bright" +msgstr "Tasten Helligkeit" + +#: PiFinder/ui/menu_structure.py:567 +msgid "Sleep Time" +msgstr "Ruhezustand" + +#: PiFinder/ui/menu_structure.py:573 PiFinder/ui/menu_structure.py:605 +#: PiFinder/ui/menu_structure.py:629 PiFinder/ui/menu_structure.py:678 +#: PiFinder/ui/menu_structure.py:702 PiFinder/ui/menu_structure.py:726 +#: PiFinder/ui/menu_structure.py:750 +msgid "Off" +msgstr "Aus" + +#: PiFinder/ui/menu_structure.py:599 +msgid "Menu Anim" +msgstr "Menu Animation" + +#: PiFinder/ui/menu_structure.py:609 PiFinder/ui/menu_structure.py:633 +msgid "Fast" +msgstr "Schnell" + +#: PiFinder/ui/menu_structure.py:613 PiFinder/ui/menu_structure.py:637 +#: PiFinder/ui/menu_structure.py:686 PiFinder/ui/menu_structure.py:710 +#: PiFinder/ui/menu_structure.py:734 +msgid "Medium" +msgstr "Mittel" + +#: PiFinder/ui/menu_structure.py:617 PiFinder/ui/menu_structure.py:641 +msgid "Slow" +msgstr "Langsam" + +#: PiFinder/ui/menu_structure.py:623 +msgid "Scroll Speed" +msgstr "Scrollgeschwindigkeit" + +#: PiFinder/ui/menu_structure.py:647 +msgid "Az Arrows" +msgstr "Az Pfeile" + +#: PiFinder/ui/menu_structure.py:654 +msgid "Default" +msgstr "Standard" + +#: PiFinder/ui/menu_structure.py:658 +msgid "Reverse" +msgstr "Umgekehrt" + +#: PiFinder/ui/menu_structure.py:666 +msgid "Chart..." +msgstr "Karte..." + +#: PiFinder/ui/menu_structure.py:672 +msgid "Reticle" +msgstr "Fadenkreuz" + +#: PiFinder/ui/menu_structure.py:682 PiFinder/ui/menu_structure.py:706 +#: PiFinder/ui/menu_structure.py:730 +msgid "Low" +msgstr "niedrig" + +#: PiFinder/ui/menu_structure.py:690 PiFinder/ui/menu_structure.py:714 +#: PiFinder/ui/menu_structure.py:738 +msgid "High" +msgstr "hoch" + +#: PiFinder/ui/menu_structure.py:696 +msgid "Constellation" +msgstr "Sternbilder" + +#: PiFinder/ui/menu_structure.py:720 +msgid "DSO Display" +msgstr "DSO Anzeige" + +#: PiFinder/ui/menu_structure.py:744 +msgid "RA/DEC Disp." +msgstr "RA/DEC Anzeige" + +#: PiFinder/ui/menu_structure.py:754 +msgid "HH:MM" +msgstr "HH:MM" + +#: PiFinder/ui/menu_structure.py:758 +msgid "Degrees" +msgstr "Grad" + +#: PiFinder/ui/menu_structure.py:766 +msgid "Camera Exp" +msgstr "BLZ" + +#: PiFinder/ui/menu_structure.py:774 +msgid "0.025s" +msgstr "0,025s" + +#: PiFinder/ui/menu_structure.py:778 +msgid "0.05s" +msgstr "0,05s" + +#: PiFinder/ui/menu_structure.py:782 +msgid "0.1s" +msgstr "0,1s" + +#: PiFinder/ui/menu_structure.py:786 +msgid "0.2s" +msgstr "0,2s" + +#: PiFinder/ui/menu_structure.py:790 +msgid "0.4s" +msgstr "0.4s" + +#: PiFinder/ui/menu_structure.py:794 +msgid "0.8s" +msgstr "0.8s" + +#: PiFinder/ui/menu_structure.py:798 +msgid "1s" +msgstr "1s" + +#: PiFinder/ui/menu_structure.py:804 +msgid "WiFi Mode" +msgstr "WLAN" + +#: PiFinder/ui/menu_structure.py:822 +msgid "PiFinder Type" +msgstr "PiFinder Art" + +#: PiFinder/ui/menu_structure.py:829 +msgid "Left" +msgstr "Links" + +#: PiFinder/ui/menu_structure.py:833 +msgid "Right" +msgstr "Rechts" + +#: PiFinder/ui/menu_structure.py:837 +msgid "Straight" +msgstr "Gerade" + +#: PiFinder/ui/menu_structure.py:841 +msgid "Flat v3" +msgstr "Flach v3" + +#: PiFinder/ui/menu_structure.py:845 +msgid "Flat v2" +msgstr "Flach v2" + +#: PiFinder/ui/menu_structure.py:851 +msgid "Mount Type" +msgstr "Montierungsart" + +#: PiFinder/ui/menu_structure.py:858 +msgid "Alt/Az" +msgstr "Azimutal" + +#: PiFinder/ui/menu_structure.py:862 +msgid "Equitorial" +msgstr "Parallaktisch" + +#: PiFinder/ui/menu_structure.py:868 +msgid "Camera Type" +msgstr "Typ Kamera" + +#: PiFinder/ui/menu_structure.py:874 +msgid "v2 - imx477" +msgstr "v2 - imx477" + +#: PiFinder/ui/menu_structure.py:879 +msgid "v3 - imx296" +msgstr "v3 - imx296" + +#: PiFinder/ui/menu_structure.py:884 +msgid "v3 - imx462" +msgstr "v3 - imx462" + +#: PiFinder/ui/menu_structure.py:893 +msgid "Tools" +msgstr "Werkzeuge" + +#: PiFinder/ui/menu_structure.py:897 +msgid "Status" +msgstr "Status" + +#: PiFinder/ui/menu_structure.py:898 +msgid "Equipment" +msgstr "Zubehör" + +#: PiFinder/ui/menu_structure.py:899 +msgid "Console" +msgstr "Konsole" + +#: PiFinder/ui/menu_structure.py:900 +msgid "Software Upd" +msgstr "Sofware Upd" + +#: PiFinder/ui/menu_structure.py:903 +msgid "Power" +msgstr "Ein/Aus" + +#: PiFinder/ui/menu_structure.py:909 +msgid "Shutdown" +msgstr "Ausschalten" + +#: PiFinder/ui/menu_structure.py:919 +msgid "Restart" +msgstr "Neu starten" + +#: PiFinder/ui/menu_structure.py:934 +msgid "Experimental" +msgstr "Experimentell" + +#: PiFinder/ui/menu_structure.py:939 +msgid "Language" +msgstr "Sprache" + +#: PiFinder/ui/menu_structure.py:946 +msgid "English" +msgstr "Englisch" + +#: PiFinder/ui/menu_structure.py:950 +msgid "German" +msgstr "Deutsch" + +#: PiFinder/ui/menu_structure.py:954 +msgid "French" +msgstr "Französisch" + +#: PiFinder/ui/menu_structure.py:958 +msgid "Spanish" +msgstr "Spanisch" + +#: PiFinder/ui/object_details.py:259 +msgid "Searching" +msgstr "Suchen" + +#: PiFinder/ui/object_details.py:275 +msgid "Calculating" +msgstr "berechnen..." + +#: PiFinder/ui/object_details.py:454 +msgid "Too Far" +msgstr "zu weit" + +#: PiFinder/ui/object_list.py:402 +msgid "No objects" +msgstr "Keine Objekte" + +#: PiFinder/ui/object_list.py:408 +msgid "match filter" +msgstr "gefiltert" + +#: PiFinder/ui/software.py:88 +msgid "Updating..." +msgstr "Update läuft..." + +#: PiFinder/ui/software.py:90 +msgid "Ok! Restarting" +msgstr "Ok! Neustart..." + +#: PiFinder/ui/software.py:93 +msgid "Error on Upd" +msgstr "Fehler beim Upd" + +#: PiFinder/ui/software.py:109 +msgid "Current Version" +msgstr "aktuelle Version" + +#: PiFinder/ui/software.py:125 +msgid "Release Version" +msgstr "Release Version" + +#: PiFinder/ui/software.py:141 +msgid "WiFi must be" +msgstr "WLAN muss im" + +#: PiFinder/ui/software.py:147 +msgid "client mode" +msgstr "client mode sein" + +#: PiFinder/ui/software.py:160 +msgid "Checking for" +msgstr "Uberprüfen" + +#: PiFinder/ui/software.py:180 +msgid "No Update" +msgstr "Kein Update" + +#: PiFinder/ui/software.py:186 +msgid "needed" +msgstr "notwendig" + +#: PiFinder/ui/software.py:196 +msgid "Update Now" +msgstr "Jetzt Updaten" + diff --git a/python/locale/es/LC_MESSAGES/messages.mo b/python/locale/es/LC_MESSAGES/messages.mo new file mode 100644 index 00000000..f0588fa2 Binary files /dev/null and b/python/locale/es/LC_MESSAGES/messages.mo differ diff --git a/python/locale/es/LC_MESSAGES/messages.po b/python/locale/es/LC_MESSAGES/messages.po new file mode 100644 index 00000000..30bc1440 --- /dev/null +++ b/python/locale/es/LC_MESSAGES/messages.po @@ -0,0 +1,739 @@ +# Spanish translations for PROJECT. +# Copyright (C) 2025 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# FIRST AUTHOR , 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2025-02-09 18:27+0100\n" +"PO-Revision-Date: 2025-01-22 17:58+0100\n" +"Last-Translator: FULL NAME \n" +"Language: es\n" +"Language-Team: es \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.16.0\n" + +#: PiFinder/ui/align.py:56 +msgid "Align Timeout" +msgstr "" + +#: PiFinder/ui/align.py:74 +msgid "Alignment Set" +msgstr "" + +#: PiFinder/ui/align.py:214 PiFinder/ui/chart.py:205 +msgid "Can't plot" +msgstr "" + +#: PiFinder/ui/align.py:220 PiFinder/ui/chart.py:211 PiFinder/ui/log.py:174 +#: PiFinder/ui/object_list.py:199 PiFinder/ui/object_list.py:219 +msgid "No Solve Yet" +msgstr "" + +#: PiFinder/ui/align.py:333 PiFinder/ui/object_details.py:444 +msgid "Aligning..." +msgstr "" + +#: PiFinder/ui/align.py:341 PiFinder/ui/object_details.py:452 +msgid "Aligned!" +msgstr "" + +#: PiFinder/ui/align.py:343 +msgid "Alignment failed" +msgstr "" + +#: PiFinder/ui/callbacks.py:51 +msgid "Filters Reset" +msgstr "" + +#: PiFinder/ui/callbacks.py:62 +msgid "Debug: Activated" +msgstr "" + +#: PiFinder/ui/callbacks.py:65 PiFinder/ui/menu_structure.py:901 +msgid "Test Mode" +msgstr "" + +#: PiFinder/ui/callbacks.py:81 +msgid "Shutting Down" +msgstr "" + +#: PiFinder/ui/callbacks.py:90 PiFinder/ui/callbacks.py:98 +msgid "Restarting..." +msgstr "" + +#: PiFinder/ui/callbacks.py:103 PiFinder/ui/callbacks.py:109 +#: PiFinder/ui/callbacks.py:115 +msgid "Switching cam" +msgstr "" + +#: PiFinder/ui/callbacks.py:150 +msgid "WiFi to AP" +msgstr "" + +#: PiFinder/ui/callbacks.py:156 +msgid "WiFi to Client" +msgstr "" + +#: PiFinder/ui/equipment.py:35 +msgid "No telescope selected" +msgstr "" + +#: PiFinder/ui/equipment.py:50 +msgid "No eyepiece selected" +msgstr "" + +#: PiFinder/ui/equipment.py:89 +msgid "Telescope..." +msgstr "" + +#: PiFinder/ui/equipment.py:100 PiFinder/ui/log.py:231 +msgid "Eyepiece..." +msgstr "" + +#: PiFinder/ui/log.py:58 +msgid "Conditions" +msgstr "" + +#: PiFinder/ui/log.py:63 +msgid "Transparency" +msgstr "" + +#. TRANSLATORS: Transparency not available +#. TRANSLATORS: Seeing not available +#. TRANSLATORS: eyepiece info not available +#: PiFinder/ui/log.py:70 PiFinder/ui/log.py:103 PiFinder/ui/log.py:261 +msgid "NA" +msgstr "" + +#: PiFinder/ui/log.py:74 PiFinder/ui/log.py:107 +msgid "Excellent" +msgstr "" + +#: PiFinder/ui/log.py:78 PiFinder/ui/log.py:111 +msgid "Very Good" +msgstr "" + +#: PiFinder/ui/log.py:82 PiFinder/ui/log.py:115 +msgid "Good" +msgstr "" + +#: PiFinder/ui/log.py:86 PiFinder/ui/log.py:119 +msgid "Fair" +msgstr "" + +#: PiFinder/ui/log.py:90 PiFinder/ui/log.py:123 +msgid "Poor" +msgstr "" + +#: PiFinder/ui/log.py:96 +msgid "Seeing" +msgstr "" + +#: PiFinder/ui/log.py:185 +msgid "SAVE Log" +msgstr "" + +#: PiFinder/ui/log.py:196 +msgid "Observability" +msgstr "" + +#: PiFinder/ui/log.py:209 +msgid "Appeal" +msgstr "" + +#: PiFinder/ui/log.py:221 +msgid "Conditions..." +msgstr "" + +#: PiFinder/ui/log.py:304 +msgid "Logged!" +msgstr "" + +#: PiFinder/ui/menu_structure.py:19 +msgid "Language: de" +msgstr "" + +#: PiFinder/ui/menu_structure.py:20 +msgid "Language: en" +msgstr "" + +#: PiFinder/ui/menu_structure.py:21 +msgid "Language: es" +msgstr "" + +#: PiFinder/ui/menu_structure.py:22 +msgid "Language: fr" +msgstr "" + +#: PiFinder/ui/menu_structure.py:33 +msgid "Camera" +msgstr "" + +#: PiFinder/ui/menu_structure.py:37 +msgid "Align" +msgstr "" + +#: PiFinder/ui/menu_structure.py:43 +msgid "Chart" +msgstr "" + +#: PiFinder/ui/menu_structure.py:49 +msgid "Objects" +msgstr "" + +#: PiFinder/ui/menu_structure.py:54 +msgid "All Filtered" +msgstr "" + +#: PiFinder/ui/menu_structure.py:59 +msgid "By Catalog" +msgstr "" + +#: PiFinder/ui/menu_structure.py:64 PiFinder/ui/menu_structure.py:245 +msgid "Planets" +msgstr "" + +#: PiFinder/ui/menu_structure.py:70 +msgid "Comets" +msgstr "" + +#: PiFinder/ui/menu_structure.py:76 PiFinder/ui/menu_structure.py:147 +#: PiFinder/ui/menu_structure.py:249 PiFinder/ui/menu_structure.py:299 +msgid "NGC" +msgstr "" + +#: PiFinder/ui/menu_structure.py:82 PiFinder/ui/menu_structure.py:141 +#: PiFinder/ui/menu_structure.py:253 PiFinder/ui/menu_structure.py:295 +msgid "Messier" +msgstr "" + +#: PiFinder/ui/menu_structure.py:88 PiFinder/ui/menu_structure.py:257 +msgid "DSO..." +msgstr "" + +#: PiFinder/ui/menu_structure.py:93 PiFinder/ui/menu_structure.py:263 +msgid "Abell Pn" +msgstr "" + +#: PiFinder/ui/menu_structure.py:99 PiFinder/ui/menu_structure.py:267 +msgid "Arp Galaxies" +msgstr "" + +#: PiFinder/ui/menu_structure.py:105 PiFinder/ui/menu_structure.py:271 +msgid "Barnard" +msgstr "" + +#: PiFinder/ui/menu_structure.py:111 PiFinder/ui/menu_structure.py:275 +msgid "Caldwell" +msgstr "" + +#: PiFinder/ui/menu_structure.py:117 PiFinder/ui/menu_structure.py:279 +msgid "Collinder" +msgstr "" + +#: PiFinder/ui/menu_structure.py:123 PiFinder/ui/menu_structure.py:283 +msgid "E.G. Globs" +msgstr "" + +#: PiFinder/ui/menu_structure.py:129 PiFinder/ui/menu_structure.py:287 +msgid "Herschel 400" +msgstr "" + +#: PiFinder/ui/menu_structure.py:135 PiFinder/ui/menu_structure.py:291 +msgid "IC" +msgstr "" + +#: PiFinder/ui/menu_structure.py:153 PiFinder/ui/menu_structure.py:303 +msgid "Sharpless" +msgstr "" + +#: PiFinder/ui/menu_structure.py:159 PiFinder/ui/menu_structure.py:307 +msgid "TAAS 200" +msgstr "" + +#: PiFinder/ui/menu_structure.py:167 PiFinder/ui/menu_structure.py:313 +msgid "Stars..." +msgstr "" + +#: PiFinder/ui/menu_structure.py:172 PiFinder/ui/menu_structure.py:319 +msgid "Bright Named" +msgstr "" + +#: PiFinder/ui/menu_structure.py:178 PiFinder/ui/menu_structure.py:323 +msgid "SAC Doubles" +msgstr "" + +#: PiFinder/ui/menu_structure.py:184 PiFinder/ui/menu_structure.py:327 +msgid "SAC Asterisms" +msgstr "" + +#: PiFinder/ui/menu_structure.py:190 PiFinder/ui/menu_structure.py:331 +msgid "SAC Red Stars" +msgstr "" + +#: PiFinder/ui/menu_structure.py:196 PiFinder/ui/menu_structure.py:335 +msgid "RASC Doubles" +msgstr "" + +#: PiFinder/ui/menu_structure.py:202 PiFinder/ui/menu_structure.py:339 +msgid "TLK 90 Variables" +msgstr "" + +#: PiFinder/ui/menu_structure.py:212 +msgid "Recent" +msgstr "" + +#: PiFinder/ui/menu_structure.py:218 +msgid "Name Search" +msgstr "" + +#: PiFinder/ui/menu_structure.py:224 +msgid "Filter" +msgstr "" + +#: PiFinder/ui/menu_structure.py:230 +msgid "Reset All" +msgstr "" + +#: PiFinder/ui/menu_structure.py:234 PiFinder/ui/menu_structure.py:925 +msgid "Confirm" +msgstr "" + +#: PiFinder/ui/menu_structure.py:235 PiFinder/ui/menu_structure.py:928 +#: PiFinder/ui/software.py:202 +msgid "Cancel" +msgstr "" + +#: PiFinder/ui/menu_structure.py:239 +msgid "Catalogs" +msgstr "" + +#: PiFinder/ui/menu_structure.py:347 +msgid "Type" +msgstr "" + +#: PiFinder/ui/menu_structure.py:353 +msgid "Galaxy" +msgstr "" + +#: PiFinder/ui/menu_structure.py:357 +msgid "Open Cluster" +msgstr "" + +#: PiFinder/ui/menu_structure.py:361 +msgid "Cluster/Neb" +msgstr "" + +#: PiFinder/ui/menu_structure.py:365 +msgid "Globular" +msgstr "" + +#: PiFinder/ui/menu_structure.py:369 +msgid "Nebula" +msgstr "" + +#: PiFinder/ui/menu_structure.py:373 +msgid "P. Nebula" +msgstr "" + +#: PiFinder/ui/menu_structure.py:377 +msgid "Dark Nebula" +msgstr "" + +#: PiFinder/ui/menu_structure.py:381 +msgid "Star" +msgstr "" + +#: PiFinder/ui/menu_structure.py:385 +msgid "Double Str" +msgstr "" + +#: PiFinder/ui/menu_structure.py:389 +msgid "Triple Str" +msgstr "" + +#: PiFinder/ui/menu_structure.py:393 +msgid "Knot" +msgstr "" + +#: PiFinder/ui/menu_structure.py:397 +msgid "Asterism" +msgstr "" + +#: PiFinder/ui/menu_structure.py:401 +msgid "Planet" +msgstr "" + +#: PiFinder/ui/menu_structure.py:405 +msgid "Comet" +msgstr "" + +#: PiFinder/ui/menu_structure.py:411 +msgid "Altitude" +msgstr "" + +#: PiFinder/ui/menu_structure.py:417 PiFinder/ui/menu_structure.py:449 +msgid "None" +msgstr "" + +#: PiFinder/ui/menu_structure.py:443 +msgid "Magnitude" +msgstr "" + +#: PiFinder/ui/menu_structure.py:495 PiFinder/ui/menu_structure.py:505 +msgid "Observed" +msgstr "" + +#: PiFinder/ui/menu_structure.py:501 +msgid "Any" +msgstr "" + +#: PiFinder/ui/menu_structure.py:509 +msgid "Not Observed" +msgstr "" + +#: PiFinder/ui/menu_structure.py:517 +msgid "Settings" +msgstr "" + +#: PiFinder/ui/menu_structure.py:522 +msgid "User Pref..." +msgstr "" + +#: PiFinder/ui/menu_structure.py:527 +msgid "Key Bright" +msgstr "" + +#: PiFinder/ui/menu_structure.py:567 +msgid "Sleep Time" +msgstr "" + +#: PiFinder/ui/menu_structure.py:573 PiFinder/ui/menu_structure.py:605 +#: PiFinder/ui/menu_structure.py:629 PiFinder/ui/menu_structure.py:678 +#: PiFinder/ui/menu_structure.py:702 PiFinder/ui/menu_structure.py:726 +#: PiFinder/ui/menu_structure.py:750 +msgid "Off" +msgstr "" + +#: PiFinder/ui/menu_structure.py:599 +msgid "Menu Anim" +msgstr "" + +#: PiFinder/ui/menu_structure.py:609 PiFinder/ui/menu_structure.py:633 +msgid "Fast" +msgstr "" + +#: PiFinder/ui/menu_structure.py:613 PiFinder/ui/menu_structure.py:637 +#: PiFinder/ui/menu_structure.py:686 PiFinder/ui/menu_structure.py:710 +#: PiFinder/ui/menu_structure.py:734 +msgid "Medium" +msgstr "" + +#: PiFinder/ui/menu_structure.py:617 PiFinder/ui/menu_structure.py:641 +msgid "Slow" +msgstr "" + +#: PiFinder/ui/menu_structure.py:623 +msgid "Scroll Speed" +msgstr "" + +#: PiFinder/ui/menu_structure.py:647 +msgid "Az Arrows" +msgstr "" + +#: PiFinder/ui/menu_structure.py:654 +msgid "Default" +msgstr "" + +#: PiFinder/ui/menu_structure.py:658 +msgid "Reverse" +msgstr "" + +#: PiFinder/ui/menu_structure.py:666 +msgid "Chart..." +msgstr "" + +#: PiFinder/ui/menu_structure.py:672 +msgid "Reticle" +msgstr "" + +#: PiFinder/ui/menu_structure.py:682 PiFinder/ui/menu_structure.py:706 +#: PiFinder/ui/menu_structure.py:730 +msgid "Low" +msgstr "" + +#: PiFinder/ui/menu_structure.py:690 PiFinder/ui/menu_structure.py:714 +#: PiFinder/ui/menu_structure.py:738 +msgid "High" +msgstr "" + +#: PiFinder/ui/menu_structure.py:696 +msgid "Constellation" +msgstr "" + +#: PiFinder/ui/menu_structure.py:720 +msgid "DSO Display" +msgstr "" + +#: PiFinder/ui/menu_structure.py:744 +msgid "RA/DEC Disp." +msgstr "" + +#: PiFinder/ui/menu_structure.py:754 +msgid "HH:MM" +msgstr "" + +#: PiFinder/ui/menu_structure.py:758 +msgid "Degrees" +msgstr "" + +#: PiFinder/ui/menu_structure.py:766 +msgid "Camera Exp" +msgstr "" + +#: PiFinder/ui/menu_structure.py:774 +msgid "0.025s" +msgstr "" + +#: PiFinder/ui/menu_structure.py:778 +msgid "0.05s" +msgstr "" + +#: PiFinder/ui/menu_structure.py:782 +msgid "0.1s" +msgstr "" + +#: PiFinder/ui/menu_structure.py:786 +msgid "0.2s" +msgstr "" + +#: PiFinder/ui/menu_structure.py:790 +msgid "0.4s" +msgstr "" + +#: PiFinder/ui/menu_structure.py:794 +msgid "0.8s" +msgstr "" + +#: PiFinder/ui/menu_structure.py:798 +msgid "1s" +msgstr "" + +#: PiFinder/ui/menu_structure.py:804 +msgid "WiFi Mode" +msgstr "" + +#: PiFinder/ui/menu_structure.py:822 +msgid "PiFinder Type" +msgstr "" + +#: PiFinder/ui/menu_structure.py:829 +msgid "Left" +msgstr "" + +#: PiFinder/ui/menu_structure.py:833 +msgid "Right" +msgstr "" + +#: PiFinder/ui/menu_structure.py:837 +msgid "Straight" +msgstr "" + +#: PiFinder/ui/menu_structure.py:841 +msgid "Flat v3" +msgstr "" + +#: PiFinder/ui/menu_structure.py:845 +msgid "Flat v2" +msgstr "" + +#: PiFinder/ui/menu_structure.py:851 +msgid "Mount Type" +msgstr "" + +#: PiFinder/ui/menu_structure.py:858 +msgid "Alt/Az" +msgstr "" + +#: PiFinder/ui/menu_structure.py:862 +msgid "Equitorial" +msgstr "" + +#: PiFinder/ui/menu_structure.py:868 +msgid "Camera Type" +msgstr "" + +#: PiFinder/ui/menu_structure.py:874 +msgid "v2 - imx477" +msgstr "" + +#: PiFinder/ui/menu_structure.py:879 +msgid "v3 - imx296" +msgstr "" + +#: PiFinder/ui/menu_structure.py:884 +msgid "v3 - imx462" +msgstr "" + +#: PiFinder/ui/menu_structure.py:893 +msgid "Tools" +msgstr "" + +#: PiFinder/ui/menu_structure.py:897 +msgid "Status" +msgstr "" + +#: PiFinder/ui/menu_structure.py:898 +msgid "Equipment" +msgstr "" + +#: PiFinder/ui/menu_structure.py:899 +msgid "Console" +msgstr "" + +#: PiFinder/ui/menu_structure.py:900 +msgid "Software Upd" +msgstr "" + +#: PiFinder/ui/menu_structure.py:903 +msgid "Power" +msgstr "" + +#: PiFinder/ui/menu_structure.py:909 +msgid "Shutdown" +msgstr "" + +#: PiFinder/ui/menu_structure.py:919 +msgid "Restart" +msgstr "" + +#: PiFinder/ui/menu_structure.py:934 +msgid "Experimental" +msgstr "" + +#: PiFinder/ui/menu_structure.py:939 +msgid "Language" +msgstr "" + +#: PiFinder/ui/menu_structure.py:946 +msgid "English" +msgstr "" + +#: PiFinder/ui/menu_structure.py:950 +msgid "German" +msgstr "" + +#: PiFinder/ui/menu_structure.py:954 +msgid "French" +msgstr "" + +#: PiFinder/ui/menu_structure.py:958 +msgid "Spanish" +msgstr "" + +#: PiFinder/ui/object_details.py:259 +msgid "Searching" +msgstr "" + +#: PiFinder/ui/object_details.py:275 +msgid "Calculating" +msgstr "" + +#: PiFinder/ui/object_details.py:454 +msgid "Too Far" +msgstr "" + +#: PiFinder/ui/object_list.py:402 +msgid "No objects" +msgstr "" + +#: PiFinder/ui/object_list.py:408 +msgid "match filter" +msgstr "" + +#: PiFinder/ui/software.py:88 +msgid "Updating..." +msgstr "" + +#: PiFinder/ui/software.py:90 +msgid "Ok! Restarting" +msgstr "" + +#: PiFinder/ui/software.py:93 +msgid "Error on Upd" +msgstr "" + +#: PiFinder/ui/software.py:109 +msgid "Current Version" +msgstr "" + +#: PiFinder/ui/software.py:125 +msgid "Release Version" +msgstr "" + +#: PiFinder/ui/software.py:141 +msgid "WiFi must be" +msgstr "" + +#: PiFinder/ui/software.py:147 +msgid "client mode" +msgstr "" + +#: PiFinder/ui/software.py:160 +msgid "Checking for" +msgstr "" + +#: PiFinder/ui/software.py:180 +msgid "No Update" +msgstr "" + +#: PiFinder/ui/software.py:186 +msgid "needed" +msgstr "" + +#: PiFinder/ui/software.py:196 +msgid "Update Now" +msgstr "" + +#~ msgid "Language: englisch" +#~ msgstr "" + +#~ msgid "language" +#~ msgstr "" + +#~ msgid "Language: Englisch" +#~ msgstr "" + +#~ msgid "Language: German" +#~ msgstr "" + +#~ msgid "Language: French" +#~ msgstr "" + +#~ msgid "Language: Spanish)" +#~ msgstr "" + +#~ msgid "english" +#~ msgstr "" + +#~ msgid "german" +#~ msgstr "" + +#~ msgid "french" +#~ msgstr "" + +#~ msgid "spanish" +#~ msgstr "" + +#~ msgid "Nearest" +#~ msgstr "" + +#~ msgid "Standard" +#~ msgstr "" + diff --git a/python/locale/fr/LC_MESSAGES/messages.mo b/python/locale/fr/LC_MESSAGES/messages.mo new file mode 100644 index 00000000..3fab9ea3 Binary files /dev/null and b/python/locale/fr/LC_MESSAGES/messages.mo differ diff --git a/python/locale/fr/LC_MESSAGES/messages.po b/python/locale/fr/LC_MESSAGES/messages.po new file mode 100644 index 00000000..71e00243 --- /dev/null +++ b/python/locale/fr/LC_MESSAGES/messages.po @@ -0,0 +1,741 @@ +# Copyright (C) 2025 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# FIRST AUTHOR , 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2025-02-09 18:27+0100\n" +"PO-Revision-Date: 2025-01-12 18:13+0100\n" +"Last-Translator: xxxxxx \n" +"Language: fr_FR\n" +"Language-Team: fr_FR \n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.16.0\n" + +#: PiFinder/ui/align.py:56 +msgid "Align Timeout" +msgstr "Temps d'alignement dépassé" + +#: PiFinder/ui/align.py:74 +msgid "Alignment Set" +msgstr "Alignement en cours" + +#: PiFinder/ui/align.py:214 PiFinder/ui/chart.py:205 +msgid "Can't plot" +msgstr "Peux pas pointer" + +#: PiFinder/ui/align.py:220 PiFinder/ui/chart.py:211 PiFinder/ui/log.py:174 +#: PiFinder/ui/object_list.py:199 PiFinder/ui/object_list.py:219 +msgid "No Solve Yet" +msgstr "Pas d'astrometrie" + +#: PiFinder/ui/align.py:333 PiFinder/ui/object_details.py:444 +#, fuzzy +msgid "Aligning..." +msgstr "Alignement..." + +#: PiFinder/ui/align.py:341 PiFinder/ui/object_details.py:452 +#, fuzzy +msgid "Aligned!" +msgstr "Alignement" + +#: PiFinder/ui/align.py:343 +msgid "Alignment failed" +msgstr "Erreur d'alignement" + +#: PiFinder/ui/callbacks.py:51 +msgid "Filters Reset" +msgstr "RàZ filtres" + +#: PiFinder/ui/callbacks.py:62 +msgid "Debug: Activated" +msgstr "Debug : actif" + +#: PiFinder/ui/callbacks.py:65 PiFinder/ui/menu_structure.py:901 +msgid "Test Mode" +msgstr "Mode Test" + +#: PiFinder/ui/callbacks.py:81 +msgid "Shutting Down" +msgstr "Arrêt" + +#: PiFinder/ui/callbacks.py:90 PiFinder/ui/callbacks.py:98 +msgid "Restarting..." +msgstr "Redémarrage" + +#: PiFinder/ui/callbacks.py:103 PiFinder/ui/callbacks.py:109 +#: PiFinder/ui/callbacks.py:115 +msgid "Switching cam" +msgstr "Bascule Caméra" + +#: PiFinder/ui/callbacks.py:150 +msgid "WiFi to AP" +msgstr "Wifi vers AP" + +#: PiFinder/ui/callbacks.py:156 +msgid "WiFi to Client" +msgstr "Wifi vers Client" + +#: PiFinder/ui/equipment.py:35 +msgid "No telescope selected" +msgstr "Pas de telescope choisi" + +#: PiFinder/ui/equipment.py:50 +msgid "No eyepiece selected" +msgstr "Pas d'oculaire choisi" + +#: PiFinder/ui/equipment.py:89 +msgid "Telescope..." +msgstr "Telescope..." + +#: PiFinder/ui/equipment.py:100 PiFinder/ui/log.py:231 +msgid "Eyepiece..." +msgstr "Oculaire" + +#: PiFinder/ui/log.py:58 +#, fuzzy +msgid "Conditions" +msgstr "Conditions" + +#: PiFinder/ui/log.py:63 +msgid "Transparency" +msgstr "Transparence" + +#. TRANSLATORS: Transparency not available +#. TRANSLATORS: Seeing not available +#. TRANSLATORS: eyepiece info not available +#: PiFinder/ui/log.py:70 PiFinder/ui/log.py:103 PiFinder/ui/log.py:261 +msgid "NA" +msgstr "NA" + +#: PiFinder/ui/log.py:74 PiFinder/ui/log.py:107 +#, fuzzy +msgid "Excellent" +msgstr "Excellent" + +#: PiFinder/ui/log.py:78 PiFinder/ui/log.py:111 +msgid "Very Good" +msgstr "Trés bon" + +#: PiFinder/ui/log.py:82 PiFinder/ui/log.py:115 +msgid "Good" +msgstr "Bon" + +#: PiFinder/ui/log.py:86 PiFinder/ui/log.py:119 +#, fuzzy +msgid "Fair" +msgstr "Moyen" + +#: PiFinder/ui/log.py:90 PiFinder/ui/log.py:123 +#, fuzzy +msgid "Poor" +msgstr "Bas" + +#: PiFinder/ui/log.py:96 +#, fuzzy +msgid "Seeing" +msgstr "Seeing" + +#: PiFinder/ui/log.py:185 +msgid "SAVE Log" +msgstr "Sauvegarde Log" + +#: PiFinder/ui/log.py:196 +msgid "Observability" +msgstr "Observation" + +#: PiFinder/ui/log.py:209 +msgid "Appeal" +msgstr "Appel" + +#: PiFinder/ui/log.py:221 +msgid "Conditions..." +msgstr "Conditions..." + +#: PiFinder/ui/log.py:304 +#, fuzzy +msgid "Logged!" +msgstr "Connecté" + +#: PiFinder/ui/menu_structure.py:19 +#, fuzzy +msgid "Language: de" +msgstr "Langage: Allemand" + +#: PiFinder/ui/menu_structure.py:20 +#, fuzzy +msgid "Language: en" +msgstr "Langage: Anglais" + +#: PiFinder/ui/menu_structure.py:21 +#, fuzzy +msgid "Language: es" +msgstr "Langage: Espagnol" + +#: PiFinder/ui/menu_structure.py:22 +#, fuzzy +msgid "Language: fr" +msgstr "Langage: Français" + +#: PiFinder/ui/menu_structure.py:33 +msgid "Camera" +msgstr "Caméra" + +#: PiFinder/ui/menu_structure.py:37 +msgid "Align" +msgstr "Alignement" + +#: PiFinder/ui/menu_structure.py:43 +msgid "Chart" +msgstr "Cartes" + +#: PiFinder/ui/menu_structure.py:49 +msgid "Objects" +msgstr "Objets" + +#: PiFinder/ui/menu_structure.py:54 +msgid "All Filtered" +msgstr "Tous filtres" + +#: PiFinder/ui/menu_structure.py:59 +msgid "By Catalog" +msgstr "Par catalogue" + +#: PiFinder/ui/menu_structure.py:64 PiFinder/ui/menu_structure.py:245 +msgid "Planets" +msgstr "Planètes" + +#: PiFinder/ui/menu_structure.py:70 +msgid "Comets" +msgstr "Comètes" + +#: PiFinder/ui/menu_structure.py:76 PiFinder/ui/menu_structure.py:147 +#: PiFinder/ui/menu_structure.py:249 PiFinder/ui/menu_structure.py:299 +msgid "NGC" +msgstr "NGC" + +#: PiFinder/ui/menu_structure.py:82 PiFinder/ui/menu_structure.py:141 +#: PiFinder/ui/menu_structure.py:253 PiFinder/ui/menu_structure.py:295 +msgid "Messier" +msgstr "Messier" + +#: PiFinder/ui/menu_structure.py:88 PiFinder/ui/menu_structure.py:257 +msgid "DSO..." +msgstr "DSO..." + +#: PiFinder/ui/menu_structure.py:93 PiFinder/ui/menu_structure.py:263 +msgid "Abell Pn" +msgstr "Abell Pn" + +#: PiFinder/ui/menu_structure.py:99 PiFinder/ui/menu_structure.py:267 +msgid "Arp Galaxies" +msgstr "Arp Galaxies" + +#: PiFinder/ui/menu_structure.py:105 PiFinder/ui/menu_structure.py:271 +msgid "Barnard" +msgstr "Barnard" + +#: PiFinder/ui/menu_structure.py:111 PiFinder/ui/menu_structure.py:275 +msgid "Caldwell" +msgstr "Caldwell" + +#: PiFinder/ui/menu_structure.py:117 PiFinder/ui/menu_structure.py:279 +msgid "Collinder" +msgstr "Collinder" + +#: PiFinder/ui/menu_structure.py:123 PiFinder/ui/menu_structure.py:283 +msgid "E.G. Globs" +msgstr "E.G. Globs" + +#: PiFinder/ui/menu_structure.py:129 PiFinder/ui/menu_structure.py:287 +msgid "Herschel 400" +msgstr "Herschel 400" + +#: PiFinder/ui/menu_structure.py:135 PiFinder/ui/menu_structure.py:291 +msgid "IC" +msgstr "IC" + +#: PiFinder/ui/menu_structure.py:153 PiFinder/ui/menu_structure.py:303 +msgid "Sharpless" +msgstr "Sharpless" + +#: PiFinder/ui/menu_structure.py:159 PiFinder/ui/menu_structure.py:307 +msgid "TAAS 200" +msgstr "TAAS 200" + +#: PiFinder/ui/menu_structure.py:167 PiFinder/ui/menu_structure.py:313 +msgid "Stars..." +msgstr "Etoiles" + +#: PiFinder/ui/menu_structure.py:172 PiFinder/ui/menu_structure.py:319 +msgid "Bright Named" +msgstr "Brillantes" + +#: PiFinder/ui/menu_structure.py:178 PiFinder/ui/menu_structure.py:323 +msgid "SAC Doubles" +msgstr "SAC Doubles" + +#: PiFinder/ui/menu_structure.py:184 PiFinder/ui/menu_structure.py:327 +msgid "SAC Asterisms" +msgstr "SAC Asterismes" + +#: PiFinder/ui/menu_structure.py:190 PiFinder/ui/menu_structure.py:331 +msgid "SAC Red Stars" +msgstr "SAC Etoiles Rouges" + +#: PiFinder/ui/menu_structure.py:196 PiFinder/ui/menu_structure.py:335 +msgid "RASC Doubles" +msgstr "RASC Doubles" + +#: PiFinder/ui/menu_structure.py:202 PiFinder/ui/menu_structure.py:339 +msgid "TLK 90 Variables" +msgstr "TLK 90 Variables" + +#: PiFinder/ui/menu_structure.py:212 +msgid "Recent" +msgstr "Récent" + +#: PiFinder/ui/menu_structure.py:218 +msgid "Name Search" +msgstr "Rech. par Nom" + +#: PiFinder/ui/menu_structure.py:224 +msgid "Filter" +msgstr "Filtre" + +#: PiFinder/ui/menu_structure.py:230 +msgid "Reset All" +msgstr "RàZ tout" + +#: PiFinder/ui/menu_structure.py:234 PiFinder/ui/menu_structure.py:925 +msgid "Confirm" +msgstr "Confirmation" + +#: PiFinder/ui/menu_structure.py:235 PiFinder/ui/menu_structure.py:928 +#: PiFinder/ui/software.py:202 +msgid "Cancel" +msgstr "Abandon" + +#: PiFinder/ui/menu_structure.py:239 +msgid "Catalogs" +msgstr "Catalogues" + +#: PiFinder/ui/menu_structure.py:347 +msgid "Type" +msgstr "Type" + +#: PiFinder/ui/menu_structure.py:353 +msgid "Galaxy" +msgstr "Galaxie" + +#: PiFinder/ui/menu_structure.py:357 +msgid "Open Cluster" +msgstr "Amas Ouvert" + +#: PiFinder/ui/menu_structure.py:361 +#, fuzzy +msgid "Cluster/Neb" +msgstr "Amas Ouvert" + +#: PiFinder/ui/menu_structure.py:365 +msgid "Globular" +msgstr "Amas Globulaire" + +#: PiFinder/ui/menu_structure.py:369 +msgid "Nebula" +msgstr "Nébuleuse" + +#: PiFinder/ui/menu_structure.py:373 +msgid "P. Nebula" +msgstr "Nébuleuse Planétaire" + +#: PiFinder/ui/menu_structure.py:377 +#, fuzzy +msgid "Dark Nebula" +msgstr "Nébuleuse obscure" + +#: PiFinder/ui/menu_structure.py:381 +#, fuzzy +msgid "Star" +msgstr "Etoile" + +#: PiFinder/ui/menu_structure.py:385 +msgid "Double Str" +msgstr "Etoile Double" + +#: PiFinder/ui/menu_structure.py:389 +#, fuzzy +msgid "Triple Str" +msgstr "Etoile Double" + +#: PiFinder/ui/menu_structure.py:393 +msgid "Knot" +msgstr "Knot" + +#: PiFinder/ui/menu_structure.py:397 +msgid "Asterism" +msgstr "Asterisme" + +#: PiFinder/ui/menu_structure.py:401 +msgid "Planet" +msgstr "Planète" + +#: PiFinder/ui/menu_structure.py:405 +#, fuzzy +msgid "Comet" +msgstr "Comètes" + +#: PiFinder/ui/menu_structure.py:411 +msgid "Altitude" +msgstr "Altitude" + +#: PiFinder/ui/menu_structure.py:417 PiFinder/ui/menu_structure.py:449 +msgid "None" +msgstr "Aucun" + +#: PiFinder/ui/menu_structure.py:443 +msgid "Magnitude" +msgstr "Magnitude" + +#: PiFinder/ui/menu_structure.py:495 PiFinder/ui/menu_structure.py:505 +msgid "Observed" +msgstr "Observé" + +#: PiFinder/ui/menu_structure.py:501 +msgid "Any" +msgstr "Tous" + +#: PiFinder/ui/menu_structure.py:509 +msgid "Not Observed" +msgstr "Non Observé" + +#: PiFinder/ui/menu_structure.py:517 +msgid "Settings" +msgstr "Réglages" + +#: PiFinder/ui/menu_structure.py:522 +msgid "User Pref..." +msgstr "Pref. Utilisateur" + +#: PiFinder/ui/menu_structure.py:527 +msgid "Key Bright" +msgstr "Brillance Touche" + +#: PiFinder/ui/menu_structure.py:567 +msgid "Sleep Time" +msgstr "Mise en Sommeil" + +#: PiFinder/ui/menu_structure.py:573 PiFinder/ui/menu_structure.py:605 +#: PiFinder/ui/menu_structure.py:629 PiFinder/ui/menu_structure.py:678 +#: PiFinder/ui/menu_structure.py:702 PiFinder/ui/menu_structure.py:726 +#: PiFinder/ui/menu_structure.py:750 +msgid "Off" +msgstr "Arret" + +#: PiFinder/ui/menu_structure.py:599 +msgid "Menu Anim" +msgstr "Anim. Menu" + +#: PiFinder/ui/menu_structure.py:609 PiFinder/ui/menu_structure.py:633 +msgid "Fast" +msgstr "Rapide" + +#: PiFinder/ui/menu_structure.py:613 PiFinder/ui/menu_structure.py:637 +#: PiFinder/ui/menu_structure.py:686 PiFinder/ui/menu_structure.py:710 +#: PiFinder/ui/menu_structure.py:734 +msgid "Medium" +msgstr "Moyen" + +#: PiFinder/ui/menu_structure.py:617 PiFinder/ui/menu_structure.py:641 +msgid "Slow" +msgstr "Lent" + +#: PiFinder/ui/menu_structure.py:623 +msgid "Scroll Speed" +msgstr "Vitesse défilement" + +#: PiFinder/ui/menu_structure.py:647 +msgid "Az Arrows" +msgstr "Fleches AZ" + +#: PiFinder/ui/menu_structure.py:654 +msgid "Default" +msgstr "Par défaut" + +#: PiFinder/ui/menu_structure.py:658 +msgid "Reverse" +msgstr "A l'envers" + +#: PiFinder/ui/menu_structure.py:666 +msgid "Chart..." +msgstr "Carte..." + +#: PiFinder/ui/menu_structure.py:672 +msgid "Reticle" +msgstr "Réticule" + +#: PiFinder/ui/menu_structure.py:682 PiFinder/ui/menu_structure.py:706 +#: PiFinder/ui/menu_structure.py:730 +msgid "Low" +msgstr "Bas" + +#: PiFinder/ui/menu_structure.py:690 PiFinder/ui/menu_structure.py:714 +#: PiFinder/ui/menu_structure.py:738 +msgid "High" +msgstr "Haut" + +#: PiFinder/ui/menu_structure.py:696 +msgid "Constellation" +msgstr "Constéllation" + +#: PiFinder/ui/menu_structure.py:720 +msgid "DSO Display" +msgstr "Affichage DSO" + +#: PiFinder/ui/menu_structure.py:744 +msgid "RA/DEC Disp." +msgstr "Affichage AD/DEC" + +#: PiFinder/ui/menu_structure.py:754 +msgid "HH:MM" +msgstr "HH:MM" + +#: PiFinder/ui/menu_structure.py:758 +msgid "Degrees" +msgstr "Degrés" + +#: PiFinder/ui/menu_structure.py:766 +msgid "Camera Exp" +msgstr "Expo. Caméra" + +#: PiFinder/ui/menu_structure.py:774 +msgid "0.025s" +msgstr "0.025s" + +#: PiFinder/ui/menu_structure.py:778 +msgid "0.05s" +msgstr "0.05s" + +#: PiFinder/ui/menu_structure.py:782 +msgid "0.1s" +msgstr "0.1s" + +#: PiFinder/ui/menu_structure.py:786 +msgid "0.2s" +msgstr "0.2s" + +#: PiFinder/ui/menu_structure.py:790 +msgid "0.4s" +msgstr "0.4s" + +#: PiFinder/ui/menu_structure.py:794 +msgid "0.8s" +msgstr "0.8s" + +#: PiFinder/ui/menu_structure.py:798 +msgid "1s" +msgstr "1s" + +#: PiFinder/ui/menu_structure.py:804 +msgid "WiFi Mode" +msgstr "Mode Wifi" + +#: PiFinder/ui/menu_structure.py:822 +msgid "PiFinder Type" +msgstr "Type de PiFinder" + +#: PiFinder/ui/menu_structure.py:829 +msgid "Left" +msgstr "Gauche" + +#: PiFinder/ui/menu_structure.py:833 +msgid "Right" +msgstr "Droit" + +#: PiFinder/ui/menu_structure.py:837 +msgid "Straight" +msgstr "Face" + +#: PiFinder/ui/menu_structure.py:841 +msgid "Flat v3" +msgstr "Plat v3" + +#: PiFinder/ui/menu_structure.py:845 +msgid "Flat v2" +msgstr "Plat v2" + +#: PiFinder/ui/menu_structure.py:851 +msgid "Mount Type" +msgstr "Type de Monture" + +#: PiFinder/ui/menu_structure.py:858 +msgid "Alt/Az" +msgstr "Alt/Az" + +#: PiFinder/ui/menu_structure.py:862 +msgid "Equitorial" +msgstr "Equatoriale" + +#: PiFinder/ui/menu_structure.py:868 +msgid "Camera Type" +msgstr "Type Caméra" + +#: PiFinder/ui/menu_structure.py:874 +msgid "v2 - imx477" +msgstr "v2 - imx477" + +#: PiFinder/ui/menu_structure.py:879 +msgid "v3 - imx296" +msgstr "v3 - imx296" + +#: PiFinder/ui/menu_structure.py:884 +#, fuzzy +msgid "v3 - imx462" +msgstr "v3 - imx462" + +#: PiFinder/ui/menu_structure.py:893 +msgid "Tools" +msgstr "Outils" + +#: PiFinder/ui/menu_structure.py:897 +msgid "Status" +msgstr "Status" + +#: PiFinder/ui/menu_structure.py:898 +msgid "Equipment" +msgstr "Equipment" + +#: PiFinder/ui/menu_structure.py:899 +msgid "Console" +msgstr "Console" + +#: PiFinder/ui/menu_structure.py:900 +msgid "Software Upd" +msgstr "Montée Logicielle" + +#: PiFinder/ui/menu_structure.py:903 +msgid "Power" +msgstr "Allumage" + +#: PiFinder/ui/menu_structure.py:909 +msgid "Shutdown" +msgstr "Arrêt" + +#: PiFinder/ui/menu_structure.py:919 +msgid "Restart" +msgstr "Redémarrage" + +#: PiFinder/ui/menu_structure.py:934 +msgid "Experimental" +msgstr "Expèrimental" + +#: PiFinder/ui/menu_structure.py:939 +#, fuzzy +msgid "Language" +msgstr "Langage" + +#: PiFinder/ui/menu_structure.py:946 +#, fuzzy +msgid "English" +msgstr "Anglais" + +#: PiFinder/ui/menu_structure.py:950 +#, fuzzy +msgid "German" +msgstr "Allemand" + +#: PiFinder/ui/menu_structure.py:954 +#, fuzzy +msgid "French" +msgstr "Français" + +#: PiFinder/ui/menu_structure.py:958 +#, fuzzy +msgid "Spanish" +msgstr "Espagnol" + +#: PiFinder/ui/object_details.py:259 +#, fuzzy +msgid "Searching" +msgstr "Réglages" + +#: PiFinder/ui/object_details.py:275 +msgid "Calculating" +msgstr "Calcul en cours" + +#: PiFinder/ui/object_details.py:454 +msgid "Too Far" +msgstr "Trop loin" + +#: PiFinder/ui/object_list.py:402 +#, fuzzy +msgid "No objects" +msgstr "Pas d'objets" + +#: PiFinder/ui/object_list.py:408 +#, fuzzy +msgid "match filter" +msgstr "Filtre de rech." + +#: PiFinder/ui/software.py:88 +#, fuzzy +msgid "Updating..." +msgstr "Redémarrage" + +#: PiFinder/ui/software.py:90 +#, fuzzy +msgid "Ok! Restarting" +msgstr "Ok! Redémarrage" + +#: PiFinder/ui/software.py:93 +msgid "Error on Upd" +msgstr "Erreur de mise à jour" + +#: PiFinder/ui/software.py:109 +msgid "Current Version" +msgstr "Version courante" + +#: PiFinder/ui/software.py:125 +msgid "Release Version" +msgstr "Version disponible" + +#: PiFinder/ui/software.py:141 +#, fuzzy +msgid "WiFi must be" +msgstr "Wifi obligatoire" + +#: PiFinder/ui/software.py:147 +#, fuzzy +msgid "client mode" +msgstr "Mode client" + +#: PiFinder/ui/software.py:160 +msgid "Checking for" +msgstr "Vérification" + +#: PiFinder/ui/software.py:180 +msgid "No Update" +msgstr "Pas de mise à jour" + +#: PiFinder/ui/software.py:186 +msgid "needed" +msgstr "Necessaire" + +#: PiFinder/ui/software.py:196 +msgid "Update Now" +msgstr "Mise à jour maintenant" + +#~ msgid "Language: Spanish" +#~ msgstr "Langage: Espagnol" + +#~ msgid "Nearest" +#~ msgstr "Plus prêt" + +#~ msgid "Standard" +#~ msgstr "Redémarrage" + diff --git a/python/noxfile.py b/python/noxfile.py index e809b7f9..7ba1d159 100644 --- a/python/noxfile.py +++ b/python/noxfile.py @@ -15,7 +15,7 @@ def lint(session: nox.Session) -> None: session (nox.Session): The Nox session being run, providing context and methods for session actions. """ session.install("ruff==0.4.8") - session.run("ruff", "check", "--fix") + session.run("ruff", "check", "--fix", "--config", "builtins=['_']") @nox.session(reuse_venv=True, python="3.9") @@ -68,14 +68,29 @@ def unit_tests(session: nox.Session) -> None: @nox.session(reuse_venv=True, python="3.9") def smoke_tests(session: nox.Session) -> None: """ - Run the project's smoke tests. + Run the project's smoke tests. + nox + This session installs the necessary dependencies and runs a subset of tests designed to quickly + check the most important functions of the program, often as a prelude to more thorough testing. - This session installs the necessary dependencies and runs a subset of tests designed to quickly - check the most important functions of the program, often as a prelude to more thorough testing. - - Args: - session (nox.Session): The Nox session being run, providing context and methods for session actions. + Args: + session (nox.Session): The Nox session being run, providing context and methods for session actions. """ session.install("-r", "requirements.txt") session.install("-r", "requirements_dev.txt") session.run("pytest", "-m", "smoke") + + +@nox.session(reuse_venv=True, python="3.9") +def babel(session: nox.Session) -> None: + """ + Run the I18N toolchain + """ + session.install("-r", "requirements.txt") + session.install("-r", "requirements_dev.txt") + + session.run( + "pybabel", "extract", "-c", "TRANSLATORS", "-o", "locale/messages.pot", "." + ) + session.run("pybabel", "update", "-i", "locale/messages.pot", "-d", "locale") + session.run("pybabel", "compile", "-d", "locale") diff --git a/python/pyproject.toml b/python/pyproject.toml index 8475104f..095d84b6 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -1,3 +1,8 @@ +[tool.babel] +mapping = [ + { "*.py" = "python" } # Scan all Python files +] + [tool.ruff] # Exclude a variety of commonly ignored directories. exclude = [ diff --git a/python/requirements_dev.txt b/python/requirements_dev.txt index 0f4f318d..3006e583 100644 --- a/python/requirements_dev.txt +++ b/python/requirements_dev.txt @@ -7,3 +7,4 @@ mypy==1.10.0 pytest==8.2.2 pygame==2.6.0 pre-commit==3.7.1 +Babel==2.16.0 \ No newline at end of file