From 9b542386fe05ff9635cd67bafe41b1b9a968f0ff Mon Sep 17 00:00:00 2001 From: A_D Date: Tue, 8 Jun 2021 16:13:46 +0200 Subject: [PATCH 01/14] added missing entry to eddb --- plugins/eddb.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/eddb.py b/plugins/eddb.py index 48ddb20f..80fd9431 100644 --- a/plugins/eddb.py +++ b/plugins/eddb.py @@ -96,6 +96,7 @@ def prefs_changed(cmdr, is_beta): def journal_entry(cmdr, is_beta, system, station, entry, state): if (ks := killswitch.get_disabled('plugins.eddb.journal')).disabled: logger.warning(f'Journal processing for EDDB has been disabled: {ks.reason}') + # LANG: Journal Processing disabled due to an active killswitch plug.show_error(_('EDDB Journal processing disabled. See Log.')) return From 40e9e0e268785cb8bd186e806ea15940bc18521f Mon Sep 17 00:00:00 2001 From: A_D Date: Tue, 8 Jun 2021 16:14:01 +0200 Subject: [PATCH 02/14] added missing entries to inara --- plugins/inara.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/plugins/inara.py b/plugins/inara.py index 2e145a3c..c2f7afeb 100644 --- a/plugins/inara.py +++ b/plugins/inara.py @@ -212,7 +212,10 @@ def plugin_prefs(parent: tk.Tk, cmdr: str, is_beta: bool) -> tk.Frame: this.log = tk.IntVar(value=config.get_int('inara_out') and 1) this.log_button = nb.Checkbutton( - frame, text=_('Send flight log and Cmdr status to Inara'), variable=this.log, command=prefsvarchanged + frame, + text=_('Send flight log and Cmdr status to Inara'), # LANG: Checkbutton to enable INARA API Usage + variable=this.log, + command=prefsvarchanged ) this.log_button.grid(columnspan=2, padx=x_button_padding, pady=(5, 0), sticky=tk.W) @@ -222,7 +225,7 @@ def plugin_prefs(parent: tk.Tk, cmdr: str, is_beta: bool) -> tk.Frame: # Section heading in settings this.label = HyperlinkLabel( frame, - text=_('Inara credentials'), + text=_('Inara credentials'), # LANG: INARA API keys link ( goes to https://inara.cz/settings-api ) background=nb.Label().cget('background'), url='https://inara.cz/settings-api', underline=True @@ -329,7 +332,7 @@ def journal_entry( # noqa: C901, CCR001 """ if (ks := killswitch.get_disabled('plugins.inara.journal')).disabled: logger.warning(f'Inara support has been disabled via killswitch: {ks.reason}') - plug.show_error(_('Inara disabled. See Log.')) + plug.show_error(_('Inara disabled. See Log.')) # LANG: INARA support disabled via killswitch return '' elif (ks := killswitch.get_disabled(f'plugins.inara.journal.event.{entry["event"]}')).disabled: @@ -1542,6 +1545,7 @@ def send_data(url: str, data: Mapping[str, Any]) -> bool: # noqa: CCR001 # Log fatal errors logger.warning(f'Inara\t{status} {reply["header"].get("eventStatusText", "")}') logger.debug(f'JSON data:\n{json.dumps(data, indent=2, separators = (",", ": "))}') + # LANG: INARA API returned some kind of error (error message will be contained in {MSG}) plug.show_error(_('Error: Inara {MSG}').format(MSG=reply['header'].get('eventStatusText', status))) else: @@ -1554,6 +1558,7 @@ def send_data(url: str, data: Mapping[str, Any]) -> bool: # noqa: CCR001 logger.debug(f'JSON data:\n{json.dumps(data_event)}') if reply_event['eventStatus'] // 100 != 2: + # LANG: INARA API returned some kind of error (error message will be contained in {MSG}) plug.show_error(_('Error: Inara {MSG}').format( MSG=f'{data_event["eventName"]},' f'{reply_event.get("eventStatusText", reply_event["eventStatus"])}' From 8d77cc039b63cb91428c4680124f4cf956345526 Mon Sep 17 00:00:00 2001 From: A_D Date: Thu, 10 Jun 2021 01:08:06 +0200 Subject: [PATCH 03/14] Added LANG comments for EDDN localisation --- plugins/eddn.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/plugins/eddn.py b/plugins/eddn.py index 8f798586..2657ab4a 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -212,7 +212,7 @@ Msg:\n{msg}''' status['text'] = '' return - localized: str = _('Sending data to EDDN...') + localized: str = _('Sending data to EDDN...') # LANG: Status text shown while attempting to send data if len(self.replaylog) == 1: status['text'] = localized @@ -260,6 +260,7 @@ Msg:\n{msg}''' except requests.exceptions.RequestException as e: logger.debug('Failed sending', exc_info=e) + # LANG: Error while trying to send data to EDDN status['text'] = _("Error: Can't connect to EDDN") return # stop sending @@ -277,15 +278,18 @@ Msg:\n{msg}''' if status_code == 429: # HTTP UPGRADE REQUIRED logger.warning('EDMC is sending schemas that are too old') + # LANG: EDDN has banned this version of our client return _('EDDN Error: EDMC is too old for EDDN. Please update.') elif status_code == 400: # we a validation check or something else. logger.warning(f'EDDN Error: {status_code} -- {exception.response}') + # LANG: EDDN returned an error that indicates something about what we sent it was wrong return _('EDDN Error: Validation Failed (EDMC Too Old?). See Log') else: logger.warning(f'Unknown status code from EDDN: {status_code} -- {exception.response}') + # LANG: EDDN returned some sort of HTTP error, one we didn't expect. {STATUS} contains a number return _('EDDN Error: Returned {STATUS} status code').format(status_code) def export_commodities(self, data: Mapping[str, Any], is_beta: bool, is_odyssey: bool) -> None: # noqa: CCR001 @@ -611,7 +615,8 @@ Msg:\n{msg}''' else: # Can't access replay file! Send immediately. - self.parent.children['status']['text'] = _('Sending data to EDDN...') # LANG: Data is being sent to EDDN + # LANG: Status text shown while attempting to send data + self.parent.children['status']['text'] = _('Sending data to EDDN...') self.parent.update_idletasks() self.send(cmdr, msg) self.parent.children['status']['text'] = '' @@ -690,6 +695,7 @@ def plugin_prefs(parent, cmdr: str, is_beta: bool) -> Frame: this.eddn_station = tk.IntVar(value=(output & config.OUT_MKT_EDDN) and 1) this.eddn_station_button = nb.Checkbutton( eddnframe, + # LANG: Enable EDDN support for station data checkbutton label text=_('Send station data to the Elite Dangerous Data Network'), variable=this.eddn_station, command=prefsvarchanged @@ -700,6 +706,7 @@ def plugin_prefs(parent, cmdr: str, is_beta: bool) -> Frame: # Output setting new in E:D 2.2 this.eddn_system_button = nb.Checkbutton( eddnframe, + # LANG: Enable EDDN support for system and other scan data checkbutton label text=_('Send system and scan data to the Elite Dangerous Data Network'), variable=this.eddn_system, command=prefsvarchanged @@ -710,6 +717,7 @@ def plugin_prefs(parent, cmdr: str, is_beta: bool) -> Frame: # Output setting under 'Send system and scan data to the Elite Dangerous Data Network' new in E:D 2.2 this.eddn_delay_button = nb.Checkbutton( eddnframe, + # LANG: EDDNs delay sending until docked option is on, this message notes that a send was skipped due to this text=_('Delay sending until docked'), variable=this.eddn_delay ) @@ -774,7 +782,7 @@ def journal_entry( # noqa: C901, CCR001 """ if (ks := killswitch.get_disabled("plugins.eddn.journal")).disabled: logger.warning(f'EDDN journal handler has been disabled via killswitch: {ks.reason}') - plug.show_error(_('EDDN journal handler disabled. See Log.')) + plug.show_error(_('EDDN journal handler disabled. See Log.')) # LANG: Killswitch disabled EDDN return None elif (ks := killswitch.get_disabled(f'plugins.eddn.journal.event.{entry["event"]}')).disabled: @@ -896,7 +904,7 @@ def journal_entry( # noqa: C901, CCR001 except requests.exceptions.RequestException as e: logger.debug('Failed in export_journal_entry', exc_info=e) - return _("Error: Can't connect to EDDN") + return _("Error: Can't connect to EDDN") # LANG: Error while trying to send data to EDDN except Exception as e: logger.debug('Failed in export_journal_entry', exc_info=e) @@ -931,7 +939,7 @@ def journal_entry( # noqa: C901, CCR001 except requests.exceptions.RequestException as e: logger.debug(f'Failed exporting {entry["event"]}', exc_info=e) - return _("Error: Can't connect to EDDN") + return _("Error: Can't connect to EDDN") # LANG: Error while trying to send data to EDDN except Exception as e: logger.debug(f'Failed exporting {entry["event"]}', exc_info=e) @@ -958,7 +966,7 @@ def cmdr_data(data: CAPIData, is_beta: bool) -> Optional[str]: # noqa: CCR001 status = this.parent.children['status'] old_status = status['text'] if not old_status: - status['text'] = _('Sending data to EDDN...') + status['text'] = _('Sending data to EDDN...') # LANG: Status text shown while attempting to send data status.update_idletasks() this.eddn.export_commodities(data, is_beta, this.odyssey) @@ -970,7 +978,7 @@ def cmdr_data(data: CAPIData, is_beta: bool) -> Optional[str]: # noqa: CCR001 except requests.RequestException as e: logger.debug('Failed exporting data', exc_info=e) - return _("Error: Can't connect to EDDN") + return _("Error: Can't connect to EDDN") # LANG: Error while trying to send data to EDDN except Exception as e: logger.debug('Failed exporting data', exc_info=e) From e89c0e9e21aa6d3824118f3a02ef20bbdfdf8677 Mon Sep 17 00:00:00 2001 From: A_D Date: Thu, 10 Jun 2021 01:08:31 +0200 Subject: [PATCH 04/14] Fixed possibly unbound variable --- scripts/find_localised_strings.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/find_localised_strings.py b/scripts/find_localised_strings.py index 60b1a03e..2bfc6b8b 100644 --- a/scripts/find_localised_strings.py +++ b/scripts/find_localised_strings.py @@ -71,6 +71,7 @@ def extract_comments(call: ast.Call, lines: list[str], file: pathlib.Path) -> Op above_line = lines[above].strip() if len(lines) >= above else None current_line = lines[current].strip() + line: Optional[str] = None bad_comment: Optional[str] = None for line in (above_line, current_line): if line is None or '#' not in line: From cba7aee8745541aa8fb0a8669e838d21c6a6a171 Mon Sep 17 00:00:00 2001 From: A_D Date: Thu, 10 Jun 2021 01:09:13 +0200 Subject: [PATCH 05/14] Fixed printed file line number sometimes off by one --- scripts/find_localised_strings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/find_localised_strings.py b/scripts/find_localised_strings.py index 2bfc6b8b..5c43b458 100644 --- a/scripts/find_localised_strings.py +++ b/scripts/find_localised_strings.py @@ -84,7 +84,7 @@ def extract_comments(call: ast.Call, lines: list[str], file: pathlib.Path) -> Op comment = match.group(1).strip() if not comment.startswith('# LANG:'): - bad_comment = f'Unknown comment for {file}:{current} {line}' + bad_comment = f'Unknown comment for {file}:{call.lineno} {line}' continue out = comment.replace('# LANG:', '').strip() @@ -95,7 +95,7 @@ def extract_comments(call: ast.Call, lines: list[str], file: pathlib.Path) -> Op print(bad_comment, file=sys.stderr) if out is None: - print(f'No comment for {file}:{current} {line}', file=sys.stderr) + print(f'No comment for {file}:{call.lineno} {line}', file=sys.stderr) return out From 21098f8cfd6999b6356820c9f90ffd6475566825 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Sun, 13 Jun 2021 12:14:01 +0100 Subject: [PATCH 06/14] stats.py: Missing LANG comment, and type ignore on some ctypes --- stats.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stats.py b/stats.py index 2eab96f2..b64a3261 100644 --- a/stats.py +++ b/stats.py @@ -35,7 +35,7 @@ if platform == 'win32': GetWindowRect.argtypes = [HWND, ctypes.POINTER(RECT)] except Exception: # Not supported under Wine 4.0 - CalculatePopupWindowPosition = None + CalculatePopupWindowPosition = None # type: ignore def status(data: Dict[str, Any]) -> List[List[str]]: @@ -275,6 +275,7 @@ class StatsDialog(): if not monitor.cmdr: return + # LANG: Fetching data from Frontier CAPI in order to display on File > Status self.status['text'] = _('Fetching data...') self.parent.update_idletasks() From 5c6a4fe68c1f8724ad94a865ddcd8c50eea498f7 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Sun, 13 Jun 2021 12:22:01 +0100 Subject: [PATCH 07/14] prefs.py: LANG comments and some slight code re-arrangement The whole LANG comment thing works best with a single `_(...)` on any given line, so splitting some of these `thing if X else other` into full conditionals. --- prefs.py | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/prefs.py b/prefs.py index ab067b6d..c07a7817 100644 --- a/prefs.py +++ b/prefs.py @@ -245,7 +245,13 @@ class PreferencesDialog(tk.Toplevel): self.parent = parent self.callback = callback - self.title(_('Preferences') if platform == 'darwin' else _('Settings')) + if platform == 'darwin': + # LANG: File > Preferences menu entry for macOS + self.title(_('Preferences')) + + else: + # LANG: File > Settings menu entry for not-macOS + self.title(_('Settings')) if parent.winfo_viewable(): self.transient(parent) @@ -336,13 +342,14 @@ class PreferencesDialog(tk.Toplevel): row = AutoInc(start=1) + # LANG: Settings > Output - choosing what data to save to files self.out_label = nb.Label(output_frame, text=_('Please choose what data to save')) self.out_label.grid(columnspan=2, padx=self.PADX, sticky=tk.W, row=row.get()) self.out_csv = tk.IntVar(value=1 if (output & config.OUT_MKT_CSV) else 0) self.out_csv_button = nb.Checkbutton( output_frame, - text=_('Market data in CSV format file'), + text=_('Market data in CSV format file'), # LANG: Settings > Output option variable=self.out_csv, command=self.outvarchanged ) @@ -351,7 +358,7 @@ class PreferencesDialog(tk.Toplevel): self.out_td = tk.IntVar(value=1 if (output & config.OUT_MKT_TD) else 0) self.out_td_button = nb.Checkbutton( output_frame, - text=_('Market data in Trade Dangerous format file'), + text=_('Market data in Trade Dangerous format file'), # LANG: Settings > Output option variable=self.out_td, command=self.outvarchanged ) @@ -361,7 +368,7 @@ class PreferencesDialog(tk.Toplevel): # Output setting self.out_ship_button = nb.Checkbutton( output_frame, - text=_('Ship loadout'), + text=_('Ship loadout'), # LANG: Settings > Output option variable=self.out_ship, command=self.outvarchanged ) @@ -371,7 +378,7 @@ class PreferencesDialog(tk.Toplevel): # Output setting self.out_auto_button = nb.Checkbutton( output_frame, - text=_('Automatically update on docking'), + text=_('Automatically update on docking'), # LANG: Settings > Output option variable=self.out_auto, command=self.outvarchanged ) @@ -379,7 +386,7 @@ class PreferencesDialog(tk.Toplevel): self.outdir = tk.StringVar() self.outdir.set(str(config.get_str('outdir'))) - # LANG: Label for "where files are located" + # LANG: Settings > Output - Label for "where files are located" self.outdir_label = nb.Label(output_frame, text=_('File location')+':') # Section heading in settings # Type ignored due to incorrect type annotation. a 2 tuple does padding for each side self.outdir_label.grid(padx=self.PADX, pady=(5, 0), sticky=tk.W, row=row.get()) # type: ignore @@ -387,9 +394,15 @@ class PreferencesDialog(tk.Toplevel): self.outdir_entry = nb.Entry(output_frame, takefocus=False) self.outdir_entry.grid(columnspan=2, padx=self.PADX, pady=(0, self.PADY), sticky=tk.EW, row=row.get()) + if platform == 'darwin': + text = (_('Change...')) # LANG: macOS Preferences > Output - files location selection button + + else: + text = (_('Browse...')) # LANG: NOT-macOS Settings > Output - files location selection button + self.outbutton = nb.Button( output_frame, - text=(_('Change...') if platform == 'darwin' else _('Browse...')), + text=text, command=lambda: self.filebrowse(_('File location'), self.outdir) ) self.outbutton.grid(column=1, padx=self.PADX, pady=self.PADY, sticky=tk.NSEW, row=row.get()) From 3a1af1c2b2e2b6d001a3c49642b3ca708f090798 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Sun, 13 Jun 2021 12:39:24 +0100 Subject: [PATCH 08/14] prefs.py: Final additional LANG comments --- prefs.py | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/prefs.py b/prefs.py index c07a7817..feb931b9 100644 --- a/prefs.py +++ b/prefs.py @@ -395,21 +395,24 @@ class PreferencesDialog(tk.Toplevel): self.outdir_entry.grid(columnspan=2, padx=self.PADX, pady=(0, self.PADY), sticky=tk.EW, row=row.get()) if platform == 'darwin': - text = (_('Change...')) # LANG: macOS Preferences > Output - files location selection button + text = (_('Change...')) # LANG: macOS Preferences - files location selection button else: - text = (_('Browse...')) # LANG: NOT-macOS Settings > Output - files location selection button + text = (_('Browse...')) # LANG: NOT-macOS Settings - files location selection button self.outbutton = nb.Button( output_frame, text=text, + # Technically this is different from the label in Settings > Output, as *this* is used + # as the title of the popup folder selection window. + # LANG: Settings > Output - Label for "where files are located" command=lambda: self.filebrowse(_('File location'), self.outdir) ) self.outbutton.grid(column=1, padx=self.PADX, pady=self.PADY, sticky=tk.NSEW, row=row.get()) nb.Frame(output_frame).grid(row=row.get()) # bottom spacer # TODO: does nothing? - # LANG: Label for 'Output' Settings tab + # LANG: Label for 'Output' Settings/Preferences tab root_notebook.add(output_frame, text=_('Output')) # Tab heading in settings def __setup_plugin_tabs(self, notebook: Notebook) -> None: @@ -432,17 +435,25 @@ class PreferencesDialog(tk.Toplevel): self.logdir.set(logdir) self.logdir_entry = nb.Entry(config_frame, takefocus=False) - # Location of the new Journal file in E:D 2.2 + # Location of the Journal files nb.Label( config_frame, + # LANG: Settings > Configuration - Label for Journal files location text=_('E:D journal file location')+':' ).grid(columnspan=4, padx=self.PADX, sticky=tk.W, row=row.get()) self.logdir_entry.grid(columnspan=4, padx=self.PADX, pady=(0, self.PADY), sticky=tk.EW, row=row.get()) + if platform == 'darwin': + text = (_('Change...')) # LANG: macOS Preferences - files location selection button + + else: + text = (_('Browse...')) # LANG: NOT-macOS Setting - files location selection button + self.logbutton = nb.Button( config_frame, - text=(_('Change...') if platform == 'darwin' else _('Browse...')), + text=text, + # LANG: Settings > Configuration - Label for Journal files location command=lambda: self.filebrowse(_('E:D journal file location'), self.logdir) ) self.logbutton.grid(column=3, padx=self.PADX, pady=self.PADY, sticky=tk.EW, row=row.get()) @@ -451,6 +462,7 @@ class PreferencesDialog(tk.Toplevel): # Appearance theme and language setting nb.Button( config_frame, + # LANG: Settings > Configuration - Label on 'reset journal files location to default' button text=_('Default'), command=self.logdir_reset, state=tk.NORMAL if config.get_str('journaldir') else tk.DISABLED @@ -477,6 +489,7 @@ class PreferencesDialog(tk.Toplevel): # Shortcut settings prompt on OSX nb.Label( config_frame, + # LANG: macOS Preferences > Configuration - restart the app message text=_('Re-start {APP} to use shortcuts').format(APP=applongname), foreground='firebrick' ).grid(padx=self.PADX, sticky=tk.W, row=row.get()) @@ -485,6 +498,7 @@ class PreferencesDialog(tk.Toplevel): # Shortcut settings prompt on OSX nb.Label( config_frame, + # LANG: macOS - Configuration - need to grant the app permission for keyboard shortcuts text=_('{APP} needs permission to use shortcuts').format(APP=applongname), foreground='firebrick' ).grid(columnspan=4, padx=self.PADX, sticky=tk.W, row=row.get()) @@ -511,6 +525,7 @@ class PreferencesDialog(tk.Toplevel): # Hotkey/Shortcut setting self.hotkey_only_btn = nb.Checkbutton( config_frame, + # LANG: Configuration - Act on hotkey only when ED is in foreground text=_('Only when Elite: Dangerous is the active app'), variable=self.hotkey_only, state=tk.NORMAL if self.hotkey_code else tk.DISABLED @@ -521,6 +536,7 @@ class PreferencesDialog(tk.Toplevel): # Hotkey/Shortcut setting self.hotkey_play_btn = nb.Checkbutton( config_frame, + # LANG: Configuration - play sound when hotkey used text=_('Play sound'), variable=self.hotkey_play, state=tk.NORMAL if self.hotkey_code else tk.DISABLED @@ -535,6 +551,7 @@ class PreferencesDialog(tk.Toplevel): self.disable_autoappupdatecheckingame = tk.IntVar(value=config.get_int('disable_autoappupdatecheckingame')) self.disable_autoappupdatecheckingame_btn = nb.Checkbutton( config_frame, + # LANG: Configuration - disable checks for app updates when in-game text=_('Disable Automatic Application Updates Check when in-game'), variable=self.disable_autoappupdatecheckingame, command=self.disable_autoappupdatecheckingame_changed @@ -584,6 +601,7 @@ class PreferencesDialog(tk.Toplevel): value=str(system_provider if system_provider in plug.provides('system_url') else 'EDSM') ) + # LANG: Configuration - Label for selection of 'System' provider website nb.Label(config_frame, text=_('System')).grid(padx=self.PADX, pady=2*self.PADY, sticky=tk.W, row=cur_row) self.system_button = nb.OptionMenu( config_frame, @@ -601,6 +619,7 @@ class PreferencesDialog(tk.Toplevel): value=str(station_provider if station_provider in plug.provides('station_url') else 'eddb') ) + # LANG: Configuration - Label for selection of 'Station' provider website nb.Label(config_frame, text=_('Station')).grid(padx=self.PADX, pady=2*self.PADY, sticky=tk.W, row=cur_row) self.station_button = nb.OptionMenu( config_frame, @@ -621,6 +640,7 @@ class PreferencesDialog(tk.Toplevel): # Set the current loglevel nb.Label( config_frame, + # LANG: Configuration - Label for selection of Log Level text=_('Log Level') ).grid(padx=self.PADX, pady=2*self.PADY, sticky=tk.W, row=cur_row) @@ -672,6 +692,7 @@ class PreferencesDialog(tk.Toplevel): appearance_frame = nb.Frame(notebook) appearance_frame.columnconfigure(2, weight=1) with row as cur_row: + # LANG: Appearance - Label for selection of application display language nb.Label(appearance_frame, text=_('Language')).grid(padx=self.PADX, sticky=tk.W, row=cur_row) self.lang_button = nb.OptionMenu(appearance_frame, self.lang, self.lang.get(), *self.languages.values()) self.lang_button.grid(column=1, columnspan=2, padx=self.PADX, sticky=tk.W, row=cur_row) @@ -713,6 +734,7 @@ class PreferencesDialog(tk.Toplevel): # Main window self.theme_button_0 = nb.ColoredButton( appearance_frame, + # LANG: Appearance - Example 'Normal' text text=_('Station'), background='grey4', command=lambda: self.themecolorbrowse(0) @@ -744,6 +766,7 @@ class PreferencesDialog(tk.Toplevel): columnspan=4, padx=self.PADX, pady=self.PADY*4, sticky=tk.EW, row=row.get() ) with row as cur_row: + # LANG: Appearance - Label for selection of UI scaling nb.Label(appearance_frame, text=_('UI Scale Percentage')).grid( padx=self.PADX, pady=2*self.PADY, sticky=tk.W, row=cur_row ) @@ -764,6 +787,7 @@ class PreferencesDialog(tk.Toplevel): self.uiscale_bar.grid(column=1, sticky=tk.W, row=cur_row) self.ui_scaling_defaultis = nb.Label( appearance_frame, + # LANG: Appearance - Help/hint text for UI scaling selection text=_('100 means Default{CR}Restart Required for{CR}changes to take effect!') ).grid(column=3, padx=self.PADX, pady=2*self.PADY, sticky=tk.E, row=cur_row) @@ -773,6 +797,7 @@ class PreferencesDialog(tk.Toplevel): ) with row as cur_row: + # LANG: Appearance - Label for selection of main window transparency nb.Label(appearance_frame, text=_("Main window transparency")).grid( padx=self.PADX, pady=self.PADY*2, sticky=tk.W, row=cur_row ) @@ -792,6 +817,7 @@ class PreferencesDialog(tk.Toplevel): nb.Label( appearance_frame, + # LANG: Appearance - Help/hint text for Main window transparency selection text=_( "100 means fully opaque.{CR}" "Window is updated in real time" @@ -813,6 +839,7 @@ class PreferencesDialog(tk.Toplevel): self.ontop_button = nb.Checkbutton( appearance_frame, + # LANG: Appearance - Label for checkbox to select if application always on top text=_('Always on top'), variable=self.always_ontop, command=self.themevarchanged @@ -890,6 +917,7 @@ class PreferencesDialog(tk.Toplevel): ttk.Separator(plugins_frame, orient=tk.HORIZONTAL).grid( columnspan=3, padx=self.PADX, pady=self.PADY * 8, sticky=tk.EW, row=row.get() ) + # LANG: Plugins - Label for list of 'enabled' plugins that don't work with Python 3.x nb.Label(plugins_frame, text=_('Plugins Without Python 3.x Support:')+':').grid(padx=self.PADX, sticky=tk.W) for plugin in plug.PLUGINS_not_py3: @@ -897,9 +925,10 @@ class PreferencesDialog(tk.Toplevel): nb.Label(plugins_frame, text=plugin.name).grid(columnspan=2, padx=self.PADX*2, sticky=tk.W) HyperlinkLabel( + # LANG: Plugins - Label on URL to documentation about migrating plugins from Python 2.7 plugins_frame, text=_('Information on migrating plugins'), background=nb.Label().cget('background'), - url='https://github.com/EDCD/EDMarketConnector/blob/main/PLUGINS.md#migration-to-python-37', + url='https://github.com/EDCD/EDMarketConnector/blob/main/PLUGINS.md#migration-from-python-27', underline=True ).grid(columnspan=2, padx=self.PADX, sticky=tk.W) ############################################################ From f449e85c0b42658bd28dd53dc1f32efc078c743d Mon Sep 17 00:00:00 2001 From: Athanasius Date: Sun, 13 Jun 2021 12:42:50 +0100 Subject: [PATCH 09/14] CAPI: 'SKUError' exception was never used - removed Also LANG comments added. --- EDMC.py | 4 ---- companion.py | 17 +++-------------- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/EDMC.py b/EDMC.py index 4120fd35..b3e6d0c9 100755 --- a/EDMC.py +++ b/EDMC.py @@ -388,10 +388,6 @@ sys.path: {sys.path}''' logger.error('Frontier CAPI Server returned an error') sys.exit(EXIT_SERVER) - except companion.SKUError: - logger.error('Frontier CAPI Server SKU problem') - sys.exit(EXIT_SERVER) - except companion.CredentialsError: logger.error('Frontier CAPI Server: Invalid Credentials') sys.exit(EXIT_CREDENTIALS) diff --git a/companion.py b/companion.py index f8cf6c26..cd099325 100644 --- a/companion.py +++ b/companion.py @@ -167,6 +167,7 @@ class ServerError(Exception): # Raised when cannot contact the Companion API server self.args = args if not args: + # LANG: Frontier CAPI didn't respond self.args = (_("Error: Frontier CAPI didn't respond"),) @@ -184,22 +185,10 @@ class ServerLagging(Exception): def __init__(self, *args) -> None: self.args = args if not args: + # LANG: Frontier CAPI data doesn't agree with latest Journal location self.args = (_('Error: Frontier server is lagging'),) -class SKUError(Exception): - """Exception Class for CAPI SKU error. - - Raised when the Companion API server thinks that the user has not - purchased E:D i.e. doesn't have the correct 'SKU'. - """ - - def __init__(self, *args) -> None: - self.args = args - if not args: - self.args = (_('Error: Frontier server SKU problem'),) - - class CredentialsError(Exception): """Exception Class for CAPI Credentials error.""" @@ -526,7 +515,7 @@ class Session(object): self.session.headers['User-Agent'] = USER_AGENT self.state = Session.STATE_OK - def query(self, endpoint: str) -> CAPIData: + def query(self, endpoint: str) -> CAPIData: # noqa: CCR001 """Perform a query against the specified CAPI endpoint.""" logger.trace(f'Performing query for endpoint "{endpoint}"') if self.state == Session.STATE_INIT: From b09a102d87065e41874e36cf0a0056d4779bd323 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Sun, 13 Jun 2021 12:51:48 +0100 Subject: [PATCH 10/14] companion.py: Final LANG comments added. --- companion.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/companion.py b/companion.py index cd099325..56ce3b17 100644 --- a/companion.py +++ b/companion.py @@ -195,6 +195,7 @@ class CredentialsError(Exception): def __init__(self, *args) -> None: self.args = args if not args: + # LANG: Generic "something went wrong with Frontier Auth" error self.args = (_('Error: Invalid Credentials'),) @@ -210,6 +211,7 @@ class CmdrError(Exception): def __init__(self, *args) -> None: self.args = args if not args: + # LANG: Frontier CAPI authorisation not for currently game-active commander self.args = (_('Error: Wrong Cmdr'),) @@ -320,6 +322,7 @@ class Auth(object): (data[k] for k in ('error_description', 'error', 'message') if k in data), '' ) + # LANG: Generic error prefix - following text is from Frontier auth service raise CredentialsError(f'{_("Error")}: {error!r}') r = None @@ -358,15 +361,18 @@ class Auth(object): if (usr := data_decode.get('usr')) is None: logger.error('No "usr" in /decode data') + # LANG: Frontier auth, no 'usr' section in returned data raise CredentialsError(_("Error: Couldn't check token customer_id")) if (customer_id := usr.get('customer_id')) is None: logger.error('No "usr"->"customer_id" in /decode data') + # LANG: Frontier auth, no 'customer_id' in 'usr' section in returned data raise CredentialsError(_("Error: Couldn't check token customer_id")) # All 'FID' seen in Journals so far have been 'F' # Frontier, Steam and Epic if f'F{customer_id}' != monitor.state.get('FID'): + # LANG: Frontier auth customer_id doesn't match game session FID raise CredentialsError(_("Error: customer_id doesn't match!")) logger.info(f'Frontier CAPI Auth: New token for \"{self.cmdr}\"') @@ -388,6 +394,7 @@ class Auth(object): if r: self.dump(r) + # LANG: Failed to get Access Token from Frontier Auth service raise CredentialsError(_('Error: unable to get token')) from e logger.error(f"Frontier CAPI Auth: Can't get token for \"{self.cmdr}\"") @@ -396,6 +403,7 @@ class Auth(object): (data[k] for k in ('error_description', 'error', 'message') if k in data), '' ) + # LANG: Generic error prefix - following text is from Frontier auth service raise CredentialsError(f'{_("Error")}: {error!r}') @staticmethod @@ -536,6 +544,7 @@ class Session(object): except Exception as e: logger.debug('Attempting GET', exc_info=e) + # LANG: Frontier CAPI data retrieval failed raise ServerError(f'{_("Frontier CAPI query failure")}: {endpoint}') from e if r.url.startswith(SERVER_AUTH): @@ -551,6 +560,7 @@ class Session(object): # Server error. Typically 500 "Internal Server Error" if server is down logger.debug('500 status back from CAPI') self.dump(r) + # LANG: Frontier CAPI data retrieval failed with 5XX code raise ServerError(f'{_("Frontier CAPI server error")}: {r.status_code}') try: From 7552e93f07fb84858eab864545808fc46d17d14d Mon Sep 17 00:00:00 2001 From: Athanasius Date: Sun, 13 Jun 2021 12:59:50 +0100 Subject: [PATCH 11/14] EDMarketConnector: Final LANG comments --- EDMarketConnector.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/EDMarketConnector.py b/EDMarketConnector.py index 93869299..5d8cb08a 100755 --- a/EDMarketConnector.py +++ b/EDMarketConnector.py @@ -497,6 +497,7 @@ class AppWindow(object): self.always_ontop = tk.BooleanVar(value=bool(config.get_int('always_ontop'))) self.system_menu = tk.Menu(self.menubar, name='system', tearoff=tk.FALSE) self.system_menu.add_separator() + # LANG: Appearance - Label for checkbox to select if application always on top self.system_menu.add_checkbutton(label=_('Always on top'), variable=self.always_ontop, command=self.ontop_changed) # Appearance setting @@ -749,6 +750,7 @@ class AppWindow(object): def login(self): """Initiate CAPI/Frontier login and set other necessary state.""" if not self.status['text']: + # LANG: Status - Attempting to get a Frontier Auth Access Token self.status['text'] = _('Logging in...') self.button['state'] = self.theme_button['state'] = tk.DISABLED @@ -803,10 +805,12 @@ class AppWindow(object): elif (config.get_int('output') & config.OUT_MKT_EDDN) \ and not (data['lastStarport'].get('commodities') or data['lastStarport'].get('modules')): if not self.status['text']: + # LANG: Status - Either no station market or modules data from Frontier CAPI self.status['text'] = _("Station doesn't have anything!") elif not data['lastStarport'].get('commodities'): if not self.status['text']: + # LANG: Status - No station market data from Frontier CAPI self.status['text'] = _("Station doesn't have a market!") elif config.get_int('output') & (config.OUT_MKT_CSV | config.OUT_MKT_TD): @@ -851,6 +855,7 @@ class AppWindow(object): elif play_sound: hotkeymgr.play_good() + # LANG: Status - Attempting to retrieve data from Frontier CAPI self.status['text'] = _('Fetching data...') self.button['state'] = self.theme_button['state'] = tk.DISABLED self.w.update_idletasks() @@ -1263,7 +1268,7 @@ class AppWindow(object): if time() < self.holdofftime: # Update button in main window self.button['text'] = self.theme_button['text'] \ - = _('cooldown {SS}s').format(SS=int(self.holdofftime - time())) + = _('cooldown {SS}s').format(SS=int(self.holdofftime - time())) # LANG: Cooldown on 'Update' button self.w.after(1000, self.cooldown) else: @@ -1311,6 +1316,7 @@ class AppWindow(object): tk.Toplevel.__init__(self, parent) self.parent = parent + # LANG: Help>About - 'About app' label self.title(_('About {APP}').format(APP=applongname)) if parent.winfo_viewable(): @@ -1344,6 +1350,7 @@ class AppWindow(object): row += 1 self.appversion_label = tk.Label(frame, text=appversion()) self.appversion_label.grid(row=row, column=0, sticky=tk.E) + # LANG: Help>About - Label on URL for release notes self.appversion = HyperlinkLabel(frame, compound=tk.RIGHT, text=_('Release Notes'), url='https://github.com/EDCD/EDMarketConnector/releases/tag/Release/' f'{appversion_nobuild()}', @@ -1369,6 +1376,7 @@ class AppWindow(object): # OK button to close the window ttk.Label(frame).grid(row=row, column=0) # spacer row += 1 + # LANG: Generic 'OK' button label button = ttk.Button(frame, text=_('OK'), command=self.apply) button.grid(row=row, column=2, sticky=tk.E) button.bind("", lambda event: self.apply()) @@ -1389,6 +1397,7 @@ class AppWindow(object): def save_raw(self) -> None: # noqa: CCR001 # Not easily broken up. """Save newly acquired CAPI data in the configured file.""" + # LANG: Status - Attempting to retrieve data from Frontier CAPI to save to file self.status['text'] = _('Fetching data...') self.w.update_idletasks() @@ -1735,6 +1744,7 @@ sys.path: {sys.path}''' """Display message about plugins not updated for Python 3.x.""" plugins_not_py3_last = config.get_int('plugins_not_py3_last', default=0) if (plugins_not_py3_last + 86400) < int(time()) and len(plug.PLUGINS_not_py3): + # LANG: Popup-text about 'active' plugins without Python 3.x support popup_text = _( "One or more of your enabled plugins do not yet have support for Python 3.x. Please see the " "list on the '{PLUGINS}' tab of '{FILE}' > '{SETTINGS}'. You should check if there is an " @@ -1752,6 +1762,7 @@ sys.path: {sys.path}''' popup_text = popup_text.replace('\\r', '\r') tk.messagebox.showinfo( + # LANG: Popup window title for list of 'enabled' plugins that don't work with Python 3.x _('EDMC: Plugins Without Python 3.x Support'), popup_text ) From 4f1f07957c0d2ff9721cd821028e0ecd1f9c1363 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Sun, 13 Jun 2021 13:02:13 +0100 Subject: [PATCH 12/14] journal_lock: LANG comments --- journal_lock.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/journal_lock.py b/journal_lock.py index 318eff6b..d038709d 100644 --- a/journal_lock.py +++ b/journal_lock.py @@ -202,6 +202,7 @@ class JournalLock: self.parent = parent self.callback = callback + # LANG: Title text on popup when Journal directory already locked self.title(_('Journal directory already locked')) # remove decoration @@ -218,13 +219,16 @@ class JournalLock: frame.grid(sticky=tk.NSEW) self.blurb = tk.Label(frame) + # LANG: Text for when newly selected Journal directory is already locked self.blurb['text'] = _("The new Journal Directory location is already locked.{CR}" "You can either attempt to resolve this and then Retry, or choose to Ignore this.") self.blurb.grid(row=1, column=0, columnspan=2, sticky=tk.NSEW) + # LANG: Generic 'Retry' button label self.retry_button = ttk.Button(frame, text=_('Retry'), command=self.retry) self.retry_button.grid(row=2, column=0, sticky=tk.EW) + # LANG: Generic 'Ignore' button label self.ignore_button = ttk.Button(frame, text=_('Ignore'), command=self.ignore) self.ignore_button.grid(row=2, column=1, sticky=tk.EW) self.protocol("WM_DELETE_WINDOW", self._destroy) From 5ad3ec8d8f352ba305b1af0f9d5f126d41d634e4 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Sun, 13 Jun 2021 13:10:14 +0100 Subject: [PATCH 13/14] plugins/coriolis: LANG comments added --- plugins/coriolis.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/plugins/coriolis.py b/plugins/coriolis.py index e28ce0d8..c05ba089 100644 --- a/plugins/coriolis.py +++ b/plugins/coriolis.py @@ -48,7 +48,11 @@ def plugin_start3(path: str) -> str: normal_textvar.set(value=normal_url) beta_textvar.set(value=beta_url) override_textvar.set( - value={'auto': _('Auto'), 'normal': _('Normal'), 'beta': _('Beta')}.get(override_mode, _('Auto')) + value={ + 'auto': _('Auto'), # LANG: 'Auto' label for Coriolis site override selection + 'normal': _('Normal'), # LANG: 'Normal' label for Coriolis site override selection + 'beta': _('Beta') # LANG: 'Beta' label for Coriolis site override selection + }.get(override_mode, _('Auto')) # LANG: 'Auto' label for Coriolis site override selection ) return 'Coriolis' @@ -61,31 +65,40 @@ def plugin_prefs(parent: tk.Widget, cmdr: str, is_beta: bool) -> tk.Frame: conf_frame = nb.Frame(parent) conf_frame.columnconfigure(index=1, weight=1) cur_row = 0 + # LANG: Settings>Coriolis: Help/hint for changing coriolis URLs nb.Label(conf_frame, text=_( "Set the URL to use with coriolis.io ship loadouts. Note that this MUST end with '/import?data='" )).grid(sticky=tk.EW, row=cur_row, column=0, columnspan=3) cur_row += 1 + # LANG: Settings>Coriolis: Label for 'NOT alpha/beta game version' URL nb.Label(conf_frame, text=_('Normal URL')).grid(sticky=tk.W, row=cur_row, column=0, padx=PADX) nb.Entry(conf_frame, textvariable=normal_textvar).grid(sticky=tk.EW, row=cur_row, column=1, padx=PADX) + # LANG: Generic 'Reset' button label nb.Button(conf_frame, text=_("Reset"), command=lambda: normal_textvar.set(value=DEFAULT_NORMAL_URL)).grid( sticky=tk.W, row=cur_row, column=2, padx=PADX ) cur_row += 1 + # LANG: Settings>Coriolis: Label for 'alpha/beta game version' URL nb.Label(conf_frame, text=_('Beta URL')).grid(sticky=tk.W, row=cur_row, column=0, padx=PADX) nb.Entry(conf_frame, textvariable=beta_textvar).grid(sticky=tk.EW, row=cur_row, column=1, padx=PADX) + # LANG: Generic 'Reset' button label nb.Button(conf_frame, text=_('Reset'), command=lambda: beta_textvar.set(value=DEFAULT_BETA_URL)).grid( sticky=tk.W, row=cur_row, column=2, padx=PADX ) cur_row += 1 + # TODO: This needs a help/hint text to be sure users know what it's for. + # LANG: Settings>Coriolis: Label for selection of using Normal, Beta or 'auto' Coriolis URL nb.Label(conf_frame, text=_('Override Beta/Normal Selection')).grid(sticky=tk.W, row=cur_row, column=0, padx=PADX) nb.OptionMenu( conf_frame, override_textvar, override_textvar.get(), - _('Normal'), _('Beta'), _('Auto') + _('Normal'), # LANG: 'Normal' label for Coriolis site override selection + _('Beta'), # LANG: 'Beta' label for Coriolis site override selection + _('Auto') # LANG: 'Auto' label for Coriolis site override selection ).grid(sticky=tk.W, row=cur_row, column=1, padx=PADX) cur_row += 1 @@ -107,7 +120,7 @@ def prefs_changed(cmdr: str, is_beta: bool) -> None: if override_mode not in ('beta', 'normal', 'auto'): logger.warning(f'Unexpected value {override_mode=!r}. defaulting to "auto"') override_mode = 'auto' - override_textvar.set(value=_('Auto')) + override_textvar.set(value=_('Auto')) # LANG: 'Auto' label for Coriolis site override selection config.set('coriolis_normal_url', normal_url) config.set('coriolis_beta_url', beta_url) @@ -117,6 +130,7 @@ def prefs_changed(cmdr: str, is_beta: bool) -> None: def _get_target_url(is_beta: bool) -> str: global override_mode if override_mode not in ('auto', 'normal', 'beta'): + # LANG: Settings>Coriolis - invalid override mode found show_error(_('Invalid Coriolis override mode!')) logger.warning(f'Unexpected override mode {override_mode!r}! defaulting to auto!') override_mode = 'auto' From 28ceb72a27a261a60a975ab6bdbd9912c817bba8 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Sun, 13 Jun 2021 13:37:21 +0100 Subject: [PATCH 14/14] plugins/edsm: LANG comments added --- plugins/edsm.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/plugins/edsm.py b/plugins/edsm.py index 458b1740..b5dbf30a 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -194,6 +194,7 @@ def plugin_prefs(parent: tk.Tk, cmdr: str, is_beta: bool) -> tk.Frame: this.log = tk.IntVar(value=config.get_int('edsm_out') and 1) this.log_button = nb.Checkbutton( + # LANG: Settings>EDSM - Label on checkbox for 'send data' frame, text=_('Send flight log and Cmdr status to EDSM'), variable=this.log, command=prefsvarchanged ) @@ -203,6 +204,7 @@ def plugin_prefs(parent: tk.Tk, cmdr: str, is_beta: bool) -> tk.Frame: # Section heading in settings this.label = HyperlinkLabel( frame, + # LANG: Settings>EDSM - Label on header/URL to EDSM API key page text=_('Elite Dangerous Star Map credentials'), background=nb.Label().cget('background'), url='https://www.edsm.net/settings/api', @@ -352,6 +354,7 @@ def journal_entry( """Journal Entry hook.""" if (ks := killswitch.get_disabled('plugins.edsm.journal')).disabled: logger.warning(f'EDSM Journal handler disabled via killswitch: {ks.reason}') + # LANG: EDSM plugin - Journal handling disabled by killswitch plug.show_error(_('EDSM Handler disabled. See Log.')) return @@ -633,6 +636,7 @@ def worker() -> None: if msg_num // 100 == 2: logger.warning(f'EDSM\t{msg_num} {msg}\t{json.dumps(pending, separators=(",", ": "))}') + # LANG: EDSM Plugin - Error message from EDSM API plug.show_error(_('Error: EDSM {MSG}').format(MSG=msg)) else: @@ -669,6 +673,7 @@ def worker() -> None: retrying += 1 else: + # LANG: EDSM Plugin - Error connecting to EDSM API plug.show_error(_("Error: Can't connect to EDSM")) if closing: @@ -731,10 +736,12 @@ def edsm_notify_system(reply: Mapping[str, Any]) -> None: """Update the image next to the system link.""" if not reply: this.system_link['image'] = this._IMG_ERROR + # LANG: EDSM Plugin - Error connecting to EDSM API plug.show_error(_("Error: Can't connect to EDSM")) elif reply['msgnum'] // 100 not in (1, 4): this.system_link['image'] = this._IMG_ERROR + # LANG: EDSM Plugin - Error message from EDSM API plug.show_error(_('Error: EDSM {MSG}').format(MSG=reply['msg'])) elif reply.get('systemCreated'):