From 45892c47481b95fac5d1f617d22086c857836e76 Mon Sep 17 00:00:00 2001 From: Luke Davis Date: Sat, 27 Jul 2024 04:55:08 -0400 Subject: [PATCH 1/2] Major improvement: use the pre_speech extensionPoint instead of patching speech.speech.speak, if supported by NVDA. Log a message informing of whether we are using the patch mechanism, or the extension point mechanism. When terminating, only un-patch if we patched in the first place. Otherwise unregister the extension point, though unnecessary. Performed some minor docs changes. --- addon/globalPlugins/speechLogger/__init__.py | 58 ++++++++++++++------ buildVars.py | 2 +- changelog.md | 6 +- readme.md | 2 +- 4 files changed, 49 insertions(+), 19 deletions(-) diff --git a/addon/globalPlugins/speechLogger/__init__.py b/addon/globalPlugins/speechLogger/__init__.py index 51cfc0a..7fb3c18 100644 --- a/addon/globalPlugins/speechLogger/__init__.py +++ b/addon/globalPlugins/speechLogger/__init__.py @@ -1,7 +1,7 @@ -# NVDA Speech Logger add-on, V24.1 +# NVDA Speech Logger add-on, V24.2 # # Copyright (C) 2022-2024 Luke Davis -# Initially based on code ideas suggested by James Scholes. +# Initially based loosely on code ideas suggested by James Scholes. # # This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. @@ -43,10 +43,17 @@ from speech.speechWithoutPauses import SpeechWithoutPauses from speech.types import SpeechSequence from speech.priorities import Spri +from characterProcessing import SymbolLevel from scriptHandler import script from logHandler import log from core import postNvdaStartup +try: + from speech.extensions import pre_speech + _USING_EXT_POINT_FOR_SPEAK: bool = True +except: + _USING_EXT_POINT_FOR_SPEAK: bool = False + from .configUI import SpeechLoggerSettings, getConf from .immutableKeyObj import ImmutableKeyObj from . import extensionPoint @@ -143,19 +150,26 @@ def __init__(self): if self.flags.logAtStartup: postNvdaStartup.register(self.startLocalLog) self.flags.loggedAtStartup = True - # Wrap speech.speech.speak, so we can get its output first - self._speak_orig = speech.speech.speak - @wraps(speech.speech.speak) - def new_speak( # noqa: C901 - sequence: SpeechSequence, - symbolLevel: Optional[int] = None, - priority: Spri = Spri.NORMAL, - *args, - **kwargs - ): - self.captureSpeech(sequence, Origin.LOCAL) - return self._speak_orig(sequence, symbolLevel, priority, *args, **kwargs) - speech.speech.speak = new_speak + # We have two ways to play here. Either an extension point, or a patch. + if _USING_EXT_POINT_FOR_SPEAK: + log.info("Using extensionPoint for speech logging of local, non-say-all, speech.") + pre_speech.register(self.captureFromExtPoint) + else: + log.info("Patching speak function for speech logging of local, non-say-all, speech.") + # Wrap speech.speech.speak, so we can get its output first + self._speak_orig = speech.speech.speak + @wraps(speech.speech.speak) + def new_speak( # noqa: C901 + sequence: SpeechSequence, + symbolLevel: Optional[int] = None, + priority: Spri = Spri.NORMAL, + *args, + **kwargs + ): + self.captureSpeech(sequence, Origin.LOCAL) + return self._speak_orig(sequence, symbolLevel, priority, *args, **kwargs) + speech.speech.speak = new_speak + # We don't have an extension point for this one yet. # Wrap speech.SpeechWithoutPauses.speechWithoutPauses.speakWithoutPauses, so we can get its output first SpeechWithoutPauses._speakWithoutPauses_orig = SpeechWithoutPauses.speakWithoutPauses SpeechWithoutPauses._speechLogger_object = self @@ -185,12 +199,15 @@ def terminate(self) -> None: gui.settingsDialogs.NVDASettingsDialog.categoryClasses.remove(SpeechLoggerSettings) # Unwrap/un-patch methods that we patched. # Note that this may screw with add-ons that patched them after we did. - speech.speech.speak = self._speak_orig + if not _USING_EXT_POINT_FOR_SPEAK: + speech.speech.speak = self._speak_orig SpeechWithoutPauses.speakWithoutPauses = SpeechWithoutPauses._speakWithoutPauses_orig # Unregister extensionPoints if self.flags.loggedAtStartup: postNvdaStartup.unregister(self.startLocalLog) extensionPoint._configChanged.unregister(self.applyUserConfig) + if _USING_EXT_POINT_FOR_SPEAK: + pre_speech.unregister(self.captureFromExtPoint) super().terminate() def startLocalLog(self, automatic: bool = True) -> bool: @@ -362,6 +379,15 @@ def dynamicLogStoppedText(self) -> str: """ return self._createDynamicLogStateText(False) + def captureFromExtPoint( + self, + speechSequence: SpeechSequence, + symbolLevel: Optional[SymbolLevel] = None, + priority: Optional[Spri] = None + ) -> None: + """Converts parameters passed from the speech extensionPoints, for use by captureSpeech.""" + self.captureSpeech(sequence=speechSequence, origin=Origin.LOCAL) + def captureSpeech(self, sequence: SpeechSequence, origin: Origin) -> None: """Receives incoming local or remote speech, and if we are capturing that kind, sends it to the appropriate file.""" file: Optional[str] = None diff --git a/buildVars.py b/buildVars.py index 83fab27..51d9b03 100644 --- a/buildVars.py +++ b/buildVars.py @@ -25,7 +25,7 @@ def _(arg): # Translators: Long description to be shown for this add-on on add-on information from add-ons manager "addon_description": _("""Logs speech utterances to a file, after the user presses an initiating key. Can also log NVDA remote session speech from the NVDA Remote add-on, to the same or another file. Optionally includes speech from say-all."""), # version - "addon_version": "24.1.7", + "addon_version": "24.2.0", # Author(s) "addon_author": "Luke Davis , James Scholes", # URL for the add-on documentation support diff --git a/changelog.md b/changelog.md index 2d192f1..db312d4 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,10 @@ +### 24.2.0 + +* Use the pre_speech extensionPoint to obtain speech, instead of patching, if supported by NVDA. Still must patch for say-all. + ### 24.1.0 -* Move the input gestures from the "tools" category, to a category named for the add-on. +* Move the input gestures from the "tools" category, to a language-specific category named for the add-on. * Compatibility with NVDA 2024.1. * Added a request for reviews to the readme. diff --git a/readme.md b/readme.md index 9f80880..966b7bf 100644 --- a/readme.md +++ b/readme.md @@ -24,7 +24,7 @@ If you can think of some use case that requires it to operate differently in dif * Separator. This combobox lets you choose one of the available utterance separators. See below for more information. * Custom separator. This field lets you enter a custom utterance separator (see below), which is used if "custom" is chosen in the combobox. * Timestamp mode. This combobox allows you to choose between no timestamps, and a timestamp at the start and end of each log session. -* Log speech during say-all (read to end) mode. This add-on logs speech generated when you press NVDA+DownArrow (NVDA+a in laptop layout). If you would rather not have that kind of narrative long reading logged, un-check this box. +* Log speech during say-all (read to end) mode. This add-on logs speech generated when you press NVDA+DownArrow (NVDA+a in laptop layout). If you would rather not have that kind of narrative (potentially long) reading logged, un-check this box. * Begin logging at startup. You can set this option to "Always", if you want speech to be logged automatically when NVDA starts. This only applies to local speech, and the default is "never". #### Utterance separator From 3e0e45cf574b4d97bd5b88d633f876f6607b4f6a Mon Sep 17 00:00:00 2001 From: NVDA translation automation Date: Fri, 16 Aug 2024 19:31:26 +0000 Subject: [PATCH 2/2] l10n updates --- addon/locale/ru/LC_MESSAGES/nvda.po | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/addon/locale/ru/LC_MESSAGES/nvda.po b/addon/locale/ru/LC_MESSAGES/nvda.po index 48afac7..1fa007c 100644 --- a/addon/locale/ru/LC_MESSAGES/nvda.po +++ b/addon/locale/ru/LC_MESSAGES/nvda.po @@ -9,14 +9,14 @@ msgstr "" "Project-Id-Version: speechLogger 24.1.4\n" "Report-Msgid-Bugs-To: nvda-translations@groups.io\n" "POT-Creation-Date: 2024-05-17 19:30+0000\n" -"PO-Revision-Date: 2024-06-15 15:40+0300\n" +"PO-Revision-Date: 2024-08-12 13:16+0500\n" "Last-Translator: Ruslan Kolodyazhni \n" "Language-Team: \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 3.4.2\n" +"X-Generator: Poedit 3.4.4\n" #. Translators: Text inserted in the log indicating logging has started. msgid "Log started" @@ -117,10 +117,10 @@ msgid "" "Configuration profile.\n" "Please close this dialog, set your config profile to normal, and try again." msgstr "" -"Дополнение регистратора речи можно настроить только в обычном профиле " -"конфигурации.\n" -"Пожалуйста, закройте этот диалог, выберите свой нормальный профиль и " -"повторите попытку." +"Дополнение регистратора речи можно настроить только в профиле конфигурации " +"по-умолчанию.\n" +"Пожалуйста, закройте этот диалог, выберите профиль конфигурации по-умолчанию " +"и повторите попытку." #. Translators: a separator option in the separators combobox msgid "Two spaces (NVDA log style)" @@ -208,7 +208,7 @@ msgstr "Режим меток времени" #. Use default #. Translators: This is the label for a checkbox to turn Say All logging on or off. msgid "Log speech during Say-&All (read to end)" -msgstr "Записывать речь в режиме полного воспроизведения (чтения до конца)" +msgstr "Записывать речь в режиме \"читать всё\" (чтения до конца)" #. Translators: this is the label for a combobox which determines whether to begin logging at startup. msgid "Begin logging at startup" @@ -221,7 +221,7 @@ msgid "" "Can also log NVDA remote session speech from the NVDA Remote add-on, to the " "same or another file. Optionally includes speech from say-all." msgstr "" -"Записывает речевые высказывания в файл после того, как пользователь нажмет " -"клавишу запуска. Также можно записывать речь удаленного сеанса NVDA из " +"Записывает речевые высказывания в файл после того, как пользователь нажмёт " +"клавишу запуска. Также можно записывать речь удалённого сеанса NVDA из " "дополнения NVDA Remote в тот же или другой файл. Дополнительно включает " -"запись речи в режиме полного воспроизведения." +"запись речи в режиме \"читать всё\"."