diff --git a/linux/keyman-config/keyman_config/uninstall_kmp.py b/linux/keyman-config/keyman_config/uninstall_kmp.py index 84c083694d..8eaac8f578 100755 --- a/linux/keyman-config/keyman_config/uninstall_kmp.py +++ b/linux/keyman-config/keyman_config/uninstall_kmp.py @@ -17,7 +17,10 @@ from keyman_config.ibus_util import (get_ibus_bus, restart_ibus, from keyman_config.kmpmetadata import get_metadata -def delete_dir(dir: str) -> bool: +error_dirs = set() + + +def _delete_dir(dir: str) -> bool: if not os.path.isdir(dir): logging.error("%s is not a directory", dir) return False @@ -28,63 +31,55 @@ def delete_dir(dir: str) -> bool: return True -def uninstall_kmp_shared(packageID): - """ - Uninstall a kmp from /usr/local/share/keyman +def _uninstall_dir(what, dir): + if os.path.isdir(dir): + if not os.access(dir, os.X_OK | os.W_OK): + error_dirs.add(dir) + return - Args: - packageID (str): Keyboard package ID - """ - kbdir = get_keyboard_dir(InstallLocation.Shared, packageID) - if not os.path.isdir(kbdir): - msg = _("Keyboard directory for %s does not exist." % packageID) - logging.error(msg) - return msg - - kbdocdir = get_keyman_doc_dir(InstallLocation.Shared, packageID) - kbfontdir = get_keyman_font_dir(InstallLocation.Shared, packageID) - - logging.info("Uninstalling shared keyboard: %s", packageID) - if not os.access(kbdir, os.X_OK | os.W_OK): # Check for write access of keyman dir - msg = _("You do not have permissions to uninstall the keyboard files. You need to run this with `sudo`") - logging.error(msg) - return msg - if os.path.isdir(kbdocdir): - if not os.access(kbdocdir, os.X_OK | os.W_OK): # Check for write access of keyman doc dir - msg = _("You do not have permissions to uninstall the documentation. You need to run this with `sudo`") - logging.error(msg) - return msg - delete_dir(kbdocdir) - logging.info("Removed documentation directory: %s", kbdocdir) + _delete_dir(dir) + logging.info('Removed %s directory %s', what, dir) else: - logging.info("No documentation directory") - if os.path.isdir(kbfontdir): - if not os.access(kbfontdir, os.X_OK | os.W_OK): # Check for write access of keyman fonts - msg = _("You do not have permissions to uninstall the font files. You need to run this with `sudo`") - logging.error(msg) - return msg - delete_dir(kbfontdir) - logging.info("Removed font directory: %s", kbfontdir) - else: - logging.info("No font directory") + logging.info('No %s directory %s', what, dir) - # need to uninstall from ibus for all lang and all kmx in kmp + +def _uninstall_kmp_common(location, packageID): + kbdir = get_keyboard_dir(location, packageID) + kbdocdir = get_keyman_doc_dir(location, packageID) + kbfontdir = get_keyman_font_dir(location, packageID) + + where = 'local' + if location == InstallLocation.Shared: + where = 'shared' + + logging.info("Uninstalling %s keyboard: %s", where, packageID) info, system, options, keyboards, files = get_metadata(kbdir) if keyboards: - if is_gnome_shell(): - uninstall_keyboards_from_gnome(keyboards, kbdir) + if is_fcitx_running(): + _uninstall_keyboards_from_fcitx5() + elif is_gnome_shell(): + _uninstall_keyboards_from_gnome(keyboards, kbdir) else: - uninstall_keyboards_from_ibus(keyboards, kbdir) + _uninstall_keyboards_from_ibus(keyboards, kbdir) else: logging.warning("could not uninstall keyboards") - delete_dir(kbdir) - logging.info("Removed keyman directory: %s", kbdir) - logging.info("Finished uninstalling shared keyboard: %s", packageID) + if not os.path.isdir(kbdir): + logging.error('Keyboard directory %s for %s does not exist.', kbdir, packageID) + + _uninstall_dir('Keyman keyboards', kbdir) + _uninstall_dir('documentation', kbdocdir) + _uninstall_dir('font', kbfontdir) + + if error_dirs: + msg = _('You do not have permission to uninstall the files in %s. You need to run this with `sudo`.') % ', '.join(error_dirs) + logging.error(msg) + return msg + + logging.info("Finished uninstalling %s keyboard: %s", where, packageID) return '' - -def uninstall_keyboards_from_ibus(keyboards, packageDir): +def _uninstall_keyboards_from_ibus(keyboards, packageDir): bus = get_ibus_bus() if bus or os.environ.get('SUDO_USER'): # install all kmx for first lang not just packageID @@ -96,7 +91,7 @@ def uninstall_keyboards_from_ibus(keyboards, packageDir): logging.warning("could not uninstall keyboards from IBus") -def uninstall_keyboards_from_gnome(keyboards, packageDir): +def _uninstall_keyboards_from_gnome(keyboards, packageDir): gnomeKeyboardsUtil = GnomeKeyboardsUtil() sources = gnomeKeyboardsUtil.read_input_sources() @@ -123,39 +118,6 @@ def _uninstall_keyboards_from_fcitx5(): return _('Please use fcitx5-configtool to remove the keyboard from the group') -def uninstall_kmp_user(packageID): - """ - Uninstall a kmp from ~/.local/share/keyman - - Args: - packageID (str): Keyboard package ID - """ - kbdir = get_keyboard_dir(InstallLocation.User, packageID) - if not os.path.isdir(kbdir): - msg = _("Keyboard directory for %s does not exist." % packageID) - logging.error(msg) - return msg - logging.info("Uninstalling local keyboard: %s", packageID) - info, system, options, keyboards, files = get_metadata(kbdir) - if keyboards: - if is_fcitx_running(): - _uninstall_keyboards_from_fcitx5() - elif is_gnome_shell(): - uninstall_keyboards_from_gnome(keyboards, kbdir) - else: - uninstall_keyboards_from_ibus(keyboards, kbdir) - else: - logging.warning("could not uninstall keyboards") - delete_dir(kbdir) - logging.info("Removed user keyman directory: %s", kbdir) - fontdir = get_keyman_font_dir(InstallLocation.User, packageID) - if os.path.isdir(fontdir): - delete_dir(fontdir) - logging.info("Removed user keyman font directory: %s", fontdir) - logging.info("Finished uninstalling local keyboard: %s", packageID) - return '' - - def uninstall_kmp(packageID, sharedarea=False): """ Uninstall a kmp @@ -165,9 +127,9 @@ def uninstall_kmp(packageID, sharedarea=False): sharedarea (str): whether to uninstall from shared /usr/local or ~/.local """ if sharedarea: - msg = uninstall_kmp_shared(packageID) + msg = _uninstall_kmp_common(InstallLocation.Shared, packageID) else: - msg = uninstall_kmp_user(packageID) + msg = _uninstall_kmp_common(InstallLocation.User, packageID) get_keyman_config_service().keyboard_list_changed() return msg diff --git a/linux/keyman-config/tests/test_uninstall_kmp.py b/linux/keyman-config/tests/test_uninstall_kmp.py index a6e2aa301b..4c48200f4c 100644 --- a/linux/keyman-config/tests/test_uninstall_kmp.py +++ b/linux/keyman-config/tests/test_uninstall_kmp.py @@ -2,7 +2,7 @@ import unittest from unittest.mock import patch -from keyman_config.uninstall_kmp import uninstall_keyboards_from_gnome +from keyman_config.uninstall_kmp import _uninstall_keyboards_from_gnome class UninstallKmpTests(unittest.TestCase): @@ -17,7 +17,7 @@ class UninstallKmpTests(unittest.TestCase): mockGnomeKeyboardsUtilInstance = self.mockGnomeKeyboardsUtilClass.return_value mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [] # Execute - uninstall_keyboards_from_gnome([{'id': 'foo1'}], 'fooDir') + _uninstall_keyboards_from_gnome([{'id': 'foo1'}], 'fooDir') # Verify mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with([]) @@ -27,7 +27,7 @@ class UninstallKmpTests(unittest.TestCase): mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [ ('ibus', 'fooDir/foo2.kmx')] # Execute - uninstall_keyboards_from_gnome([{'id': 'foo1'}], 'fooDir') + _uninstall_keyboards_from_gnome([{'id': 'foo1'}], 'fooDir') # Verify mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with([ ('ibus', 'fooDir/foo2.kmx')]) @@ -38,7 +38,7 @@ class UninstallKmpTests(unittest.TestCase): mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [ ('xkb', 'en'), ('ibus', 'fooDir/foo1.kmx')] # Execute - uninstall_keyboards_from_gnome([{'id': 'foo1'}], 'fooDir') + _uninstall_keyboards_from_gnome([{'id': 'foo1'}], 'fooDir') # Verify mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with( [('xkb', 'en')]) @@ -49,7 +49,7 @@ class UninstallKmpTests(unittest.TestCase): mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [ ('xkb', 'en'), ('ibus', 'fooDir/foo1.kmx'), ('ibus', 'fooDir/foo2.kmx')] # Execute - uninstall_keyboards_from_gnome([{'id': 'foo1'}, {'id': 'foo2'}], 'fooDir') + _uninstall_keyboards_from_gnome([{'id': 'foo1'}, {'id': 'foo2'}], 'fooDir') # Verify mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with( [('xkb', 'en')]) @@ -60,7 +60,7 @@ class UninstallKmpTests(unittest.TestCase): mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [ ('ibus', 'fooDir/foo1.kmx'), ('ibus', 'fooDir/foo2.kmx')] # Execute - uninstall_keyboards_from_gnome([{'id': 'foo1'}, {'id': 'foo2'}], 'fooDir') + _uninstall_keyboards_from_gnome([{'id': 'foo1'}, {'id': 'foo2'}], 'fooDir') # Verify mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with([]) @@ -70,7 +70,7 @@ class UninstallKmpTests(unittest.TestCase): mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [ ('xkb', 'en'), ('ibus', 'en:fooDir/foo1.kmx')] # Execute - uninstall_keyboards_from_gnome([{'id': 'foo1', 'languages': [{'id': 'en'}]}], 'fooDir') + _uninstall_keyboards_from_gnome([{'id': 'foo1', 'languages': [{'id': 'en'}]}], 'fooDir') # Verify mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with( [('xkb', 'en')]) @@ -81,7 +81,7 @@ class UninstallKmpTests(unittest.TestCase): mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [ ('xkb', 'en'), ('ibus', 'fr:fooDir/foo1.kmx')] # Execute - uninstall_keyboards_from_gnome( + _uninstall_keyboards_from_gnome( [{'id': 'foo1', 'languages': [{'id': 'en'}, {'id': 'fr'}]}], 'fooDir') # Verify mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with( @@ -93,7 +93,7 @@ class UninstallKmpTests(unittest.TestCase): mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [ ('xkb', 'en'), ('ibus', 'en:fooDir/foo1.kmx')] # Execute - uninstall_keyboards_from_gnome( + _uninstall_keyboards_from_gnome( [{'id': 'foo1', 'languages': [{'id': 'fr'}]}], 'fooDir') # Verify mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with( @@ -105,7 +105,7 @@ class UninstallKmpTests(unittest.TestCase): mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [ ('xkb', 'en'), ('ibus', 'en:fooDir/foo1.kmx'), ('ibus', 'fr:fooDir/foo1.kmx')] # Execute - uninstall_keyboards_from_gnome( + _uninstall_keyboards_from_gnome( [{'id': 'foo1', 'languages': [{'id': 'fr'}]}], 'fooDir') # Verify mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with(