[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1033918: marked as done (unblock: lios/2.7.2-5)



Your message dated Tue, 04 Apr 2023 21:28:17 +0000
with message-id <E1pjoCP-004mJB-FC@respighi.debian.org>
and subject line unblock lios
has caused the Debian Bug report #1033918,
regarding unblock: lios/2.7.2-5
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
1033918: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1033918
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock
X-Debbugs-Cc: lios@packages.debian.org
Control: affects -1 + src:lios

Hello,

I have uploaded lios/2.7.2-5 to unstable, to hopefully make it to
bookworm.

[ Reason ]
As reported on #990805 and #1033024, in the current version of lios when
opening the general preferences dialog box, lios stays stuck for a
couple minutes. This happens only when the espeak-ng package is
installed, in which case there are thousands of voices available for
the speech configuration part of this dialog box, thus making it very
long to load.

Upstream fixed the issue without telling me, we eventually found it was
fixed in a more recent upstream snapshot, and I picked up the upstream
commit for this, included in lios/2.7.2-5. The idea of the fix is to
separate the voices by language, so that the user first chooses among a
few hundred languages, and then chooses a voice person. This is enough
to make the dialog box load in a snap.

[ Impact ]
Without this new version, users will have to either remove the espeak-ng
package (but lios users are most often blind users so they do need it),
or they have to wait for several minutes when they want to change some
general preference.

[ Tests ]
This was tested manually as fixing the issue.

[ Risks ]
The code is relatively simple: in lios/speech.py, instead of having
list_voices return a plain list, it creates a dictionary sorted by
language. lios/preferences.py then contains an additional combobox, and
the logic is reworked around these to implement the two-step selection.

The upstream commit also includes selecting a default voice according to
the current locale. I prefered to avoid splitting it from the upstream
commit since the two parts seem related.

[ Checklist ]
  [X] all changes are documented in the d/changelog
  [X] I reviewed all changes and I approve them
  [X] attach debdiff against the package in testing

unblock lios/2.7.2-5
diff -Nru lios-2.7.2/debian/changelog lios-2.7.2/debian/changelog
--- lios-2.7.2/debian/changelog	2023-03-13 20:00:26.000000000 +0100
+++ lios-2.7.2/debian/changelog	2023-04-03 23:22:12.000000000 +0200
@@ -1,3 +1,10 @@
+lios (2.7.2-5) unstable; urgency=medium
+
+  * patches/preference-voice-list: Fix general preferences loading delay.
+    (Closes: #990805, #1033024).
+
+ -- Samuel Thibault <sthibault@debian.org>  Mon, 03 Apr 2023 23:22:12 +0200
+
 lios (2.7.2-4) unstable; urgency=medium
 
   * Upload fix to unstable, thanks Gunnar!
diff -Nru lios-2.7.2/debian/patches/preference-voice-list lios-2.7.2/debian/patches/preference-voice-list
--- lios-2.7.2/debian/patches/preference-voice-list	1970-01-01 01:00:00.000000000 +0100
+++ lios-2.7.2/debian/patches/preference-voice-list	2023-04-03 23:21:39.000000000 +0200
@@ -0,0 +1,232 @@
+commit 565afb783dc50d4ec7c9d1d6caf486c26f47d1fe
+Author: nalin.x.linux <nalin.x.linux@gmail.com>
+Date:   Sun Aug 28 15:27:27 2022 +0530
+
+    Preferences dialog startup fixed, speech person selection enabled, set default speech module and language using user's language
+
+---
+ lios/main.py        |   10 ++++-
+ lios/preferences.py |  104 +++++++++++++++++++++++++++++++++++++++++++++++-----
+ lios/speech.py      |   13 +++++-
+ 3 files changed, 112 insertions(+), 15 deletions(-)
+
+--- a/lios/main.py
++++ b/lios/main.py
+@@ -181,6 +181,7 @@ class linux_intelligent_ocr_solution():
+ 		#Load Preferences
+ 		self.preferences = preferences.lios_preferences()
+ 		self.preferences.set_from_file(macros.preferences_file_path)
++		self.preferences.set_default_speech_module_and_language()
+ 		self.preferences.set_avalable_scanner_drivers([ item.name for item in self.available_scanner_driver_list])
+ 		self.preferences.set_avalable_ocr_engines([ (item.name,item.get_available_languages())
+ 												for item in self.available_ocr_engine_list ])
+@@ -1379,6 +1380,7 @@ pacman -S aspell-fr"""))
+ 
+ 	def restore_preferences(self,*data):
+ 		self.preferences.__init__()
++		self.preferences.set_default_speech_module_and_language()
+ 		self.make_preferences_effective()
+ 		self.notify_information(_("Preferences Restored"),0)
+ 	
+@@ -1441,8 +1443,12 @@ pacman -S aspell-fr"""))
+ 			self.is_reading = True
+ 			speaker = speech.Speech()
+ 			speaker.set_output_module(speaker.list_output_modules()[self.preferences.speech_module])
+-			if(self.preferences.speech_module != -1 and len(speaker.list_voices()) > 1):
+-				speaker.set_synthesis_voice(speaker.list_voices()[self.preferences.speech_language])
++			language_person_dict = speaker.get_language_person_dict()
++
++			if(self.preferences.speech_module != -1 and len(language_person_dict.keys()) > 1):
++				voice = language_person_dict[list(language_person_dict)[self.preferences.speech_language]][self.preferences.speech_person]
++				speaker.set_synthesis_voice(voice)
++
+ 			speaker.set_volume(self.preferences.speech_volume)
+ 			speaker.set_pitch(self.preferences.speech_pitch)
+ 			while(not self.textview.is_cursor_at_end()):
+--- a/lios/preferences.py
++++ b/lios/preferences.py
+@@ -39,7 +39,7 @@ class lios_preferences:
+ 		self.background_color="#000";self.font_color="#fff";
+ 		self.highlight_color="#1572ffff0000";
+ 		self.background_highlight_color="#00000bacffff";
+-		self.speech_module=0;self.speech_language=10;
++		self.speech_module=-1;self.speech_language=-1;self.speech_person=-1;
+ 		self.speech_rate=0;self.speech_pitch=0;self.speech_volume=100;
+ 		self.time_between_repeated_scanning=0;self.scan_resolution=300;
+ 		self.scan_driver=1;self.scanner_cache_calibration=0;
+@@ -72,6 +72,7 @@ class lios_preferences:
+ 				self.language=int(config.get('cfg',"language"))
+ 				self.speech_module=int(config.get('cfg',"speech_module"))
+ 				self.speech_language=int(config.get('cfg',"speech_language"))
++				self.speech_person=int(config.get('cfg',"speech_person"))
+ 				self.speech_rate=int(config.get('cfg',"speech_rate"))
+ 				self.speech_volume=int(config.get('cfg',"speech_volume"))
+ 				self.speech_pitch=int(config.get('cfg',"speech_pitch"))
+@@ -96,6 +97,34 @@ class lios_preferences:
+ 		else:
+ 			self.__init__()
+ 
++	# Set speech module, language and person if speech_module is not set
++	def set_default_speech_module_and_language(self):
++		if(self.speech_module == -1):
++			test = speech.Speech()
++			output_modules_list = test.list_output_modules()
++			if("espeak-ng" in output_modules_list):
++				self.speech_module = output_modules_list.index('espeak-ng')
++				test.set_output_module('espeak-ng')
++			elif("espeak" in output_modules_list):
++				self.speech_module = output_modules_list.index('espeak')
++				test.set_output_module('espeak')
++
++			# if espeak or espeak-ng set language
++			if(self.speech_module != -1):
++				import locale
++				language_code, encoding = locale.getdefaultlocale()
++				localeValues = language_code.split('_')
++				language = localeValues[0]
++				language_person_dict = test.get_language_person_dict()
++				if(language in language_person_dict.keys()):
++					self.speech_language = list(language_person_dict.keys()).index(language)
++					self.speech_person=0;
++			else:
++				self.speech_module=0;self.speech_language=0;self.speech_person=0;
++
++			#Closing
++			test.close()
++
+ 	def save_to_file(self,filename):
+ 		#Removing old configuration file
+ 		try:
+@@ -114,6 +143,7 @@ class lios_preferences:
+ 		config.set('cfg',"language",str(self.language))
+ 		config.set('cfg',"speech_module",str(self.speech_module))
+ 		config.set('cfg',"speech_language",str(self.speech_language))
++		config.set('cfg',"speech_person",str(self.speech_person))
+ 		config.set('cfg',"speech_pitch",str(self.speech_pitch))
+ 		config.set('cfg',"speech_volume",str(self.speech_volume))
+ 		config.set('cfg',"speech_rate",str(self.speech_rate))
+@@ -161,14 +191,62 @@ class lios_preferences:
+ 			combobox_language.set_active(self.language)
+ 
+ 		def change_speech_module(*data):
+-			index_engine = combobox_speech_module.get_active()
+-			combobox_speech_language.clear()
++			module_index = combobox_speech_module.get_active()
++
+ 			test = speech.Speech()
+-			list = test.list_output_modules()
+-			test.set_output_module(list[index_engine])
+-			for item in test.list_voices():
+-				combobox_speech_language.add_item(item)
+-			combobox_speech_language.set_active(self.speech_language)
++			output_modules_list = test.list_output_modules()
++			test.set_output_module(output_modules_list[module_index])
++
++			self.speech_language_person_dict = test.get_language_person_dict()
++			test.close()
++
++			# Disconnecting for preventng function calls while clearing
++			# combobox_speech_language or adding each language to the same
++			try:
++				combobox_speech_language.disconnect_by_func(change_speech_language)
++			except(TypeError):
++				pass
++
++			combobox_speech_language.clear()
++
++			if(len(self.speech_language_person_dict.keys()) == 0):
++				combobox_speech_language.add_item(_("Default"))
++				self.speech_language = 0
++			else:
++				for item in self.speech_language_person_dict.keys():
++					combobox_speech_language.add_item(item)
++
++			combobox_speech_language.connect_change_callback_function(change_speech_language)
++
++
++			if(self.speech_language < len(self.speech_language_person_dict.keys())):
++				combobox_speech_language.set_active(self.speech_language)
++			else:
++				combobox_speech_language.set_active(0)
++				self.speech_language = 0
++
++		def change_speech_language(*data):
++			combobox_speech_person.clear()
++
++			# For users having preferences from old version
++			if(self.speech_person == -1):
++				self.speech_person = 0
++
++			if(len(list(self.speech_language_person_dict.keys())) == 0):
++				combobox_speech_person.add_item(_("Default"))
++				combobox_speech_person.set_active(0)
++				self.speech_person = 0
++				return
++
++			index_language = combobox_speech_language.get_active()
++			language = list(self.speech_language_person_dict.keys())[index_language]
++
++			for item in self.speech_language_person_dict[language]:
++				combobox_speech_person.add_item(item)
++
++			if(self.speech_person >= len(self.speech_language_person_dict[language])):
++				self.speech_person = 0
++			combobox_speech_person.set_active(self.speech_person)
+ 
+ 		def change_mode_of_rotation(*data):
+ 			if(combobox_mode_of_rotation.get_active() == 2):
+@@ -227,10 +305,14 @@ class lios_preferences:
+ 
+ 		label_speech_language = widget.Label(_("Speech-Language"))
+ 		combobox_speech_language = widget.ComboBox()
+-		combobox_speech_module.set_active(self.speech_module)
+-		combobox_speech_language.set_active(self.speech_language)
+ 		label_speech_language.set_mnemonic_widget(combobox_speech_language)
+ 
++		label_speech_person = widget.Label(_("Speech Person"))
++		combobox_speech_person = widget.ComboBox()
++		label_speech_person.set_mnemonic_widget(combobox_speech_person)
++
++		combobox_speech_module.set_active(self.speech_module)
++
+ 		label_speech_rate = widget.Label(_("Speech-Rate"))
+ 		spin_speech_rate = widget.SpinButton(self.speech_rate,-100,100,1,10,0)
+ 		label_speech_rate.set_mnemonic_widget(spin_speech_rate)
+@@ -252,6 +334,7 @@ class lios_preferences:
+ 			(label_highlight_background,1,1),(colorbutton_highlight_background,1,1),containers.Grid.NEW_ROW,
+ 			(label_speech_module,1,1),(combobox_speech_module,1,1),containers.Grid.NEW_ROW,
+ 			(label_speech_language,1,1),(combobox_speech_language,1,1),containers.Grid.NEW_ROW,
++			(label_speech_person,1,1),(combobox_speech_person,1,1),containers.Grid.NEW_ROW,
+ 			(label_speech_rate,1,1),(spin_speech_rate,1,1),containers.Grid.NEW_ROW,
+ 			(label_speech_pitch,1,1),(spin_speech_pitch,1,1),containers.Grid.NEW_ROW,
+ 			(label_speech_volume,1,1),(spin_speech_volume,1,1)])
+@@ -436,6 +519,7 @@ class lios_preferences:
+ 			self.language=combobox_language.get_active()
+ 			self.speech_module=combobox_speech_module.get_active()
+ 			self.speech_language=combobox_speech_language.get_active()
++			self.speech_person=combobox_speech_person.get_active()
+ 			self.speech_rate=spin_speech_rate.get_value()
+ 			self.speech_pitch=spin_speech_pitch.get_value()
+ 			self.speech_volume=spin_speech_volume.get_value()
+--- a/lios/speech.py
++++ b/lios/speech.py
+@@ -23,9 +23,16 @@ class Speech(speechd.SSIPClient):
+ 	def __init__(self,client_name="lios"):
+ 		super(Speech,self).__init__(client_name)
+ 		self.status = False
+-	
+-	def list_voices(self):
+-		return [ x[0] for x in self.list_synthesis_voices()]
++
++	def get_language_person_dict(self):
++		dictionary = {}
++		voices = self.list_synthesis_voices()
++		for item in voices:
++			if(item[1] not in dictionary):
++				dictionary[item[1]] = [item[0]]
++			else:
++				dictionary[item[1]].append(item[0])
++		return dictionary
+ 	
+ 	def say(self,text):
+ 		self.status = True
diff -Nru lios-2.7.2/debian/patches/series lios-2.7.2/debian/patches/series
--- lios-2.7.2/debian/patches/series	2023-03-13 19:57:48.000000000 +0100
+++ lios-2.7.2/debian/patches/series	2023-04-03 23:19:48.000000000 +0200
@@ -1,3 +1,4 @@
 tesseract_langpath
 typo
 Use-exact-versions-when-importing-Gtk-and-friends.patch
+preference-voice-list

--- End Message ---
--- Begin Message ---
Unblocked.

--- End Message ---

Reply to: