mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-10 02:45:32 +00:00
- during installation add to the list of custom keyboards if necessary - during uninstallation remove from the list of custom keyboards - if list of custom keyboards has invalid values, remove those before saving the list Closes #8598.
156 lines
5.5 KiB
Python
Executable file
156 lines
5.5 KiB
Python
Executable file
#!/usr/bin/python3
|
|
|
|
import getpass
|
|
import logging
|
|
import os
|
|
from shutil import rmtree
|
|
|
|
from keyman_config import _
|
|
from keyman_config.custom_keyboards import CustomKeyboards
|
|
from keyman_config.dbus_util import get_keyman_config_service
|
|
from keyman_config.fcitx_util import is_fcitx_running
|
|
from keyman_config.get_kmp import (InstallLocation, get_keyboard_dir,
|
|
get_keyman_doc_dir, get_keyman_font_dir)
|
|
from keyman_config.gnome_keyboards_util import (GnomeKeyboardsUtil,
|
|
get_ibus_keyboard_id,
|
|
is_gnome_shell)
|
|
from keyman_config.gsettings import GSettings
|
|
from keyman_config.ibus_util import IbusUtil, get_ibus_bus, restart_ibus
|
|
from keyman_config.kmpmetadata import get_metadata
|
|
|
|
|
|
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
|
|
if os.path.islink(dir):
|
|
os.unlink(dir)
|
|
else:
|
|
rmtree(dir)
|
|
return True
|
|
|
|
|
|
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
|
|
|
|
_delete_dir(dir)
|
|
logging.info('Removed %s directory %s', what, dir)
|
|
else:
|
|
logging.info('No %s directory %s', what, dir)
|
|
|
|
def _uninstall_kmp_common(location, packageID, removeLanguages):
|
|
kbdir = get_keyboard_dir(location, packageID)
|
|
kbdocdir = get_keyman_doc_dir(location, packageID)
|
|
kbfontdir = get_keyman_font_dir(location, packageID)
|
|
|
|
where = 'shared' if location == InstallLocation.Shared else 'user'
|
|
info, system, options, keyboards, files = get_metadata(kbdir)
|
|
if removeLanguages:
|
|
logging.info(f'Uninstalling {where} keyboard: "{packageID}"')
|
|
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)
|
|
|
|
logging.debug('Removing custom keyboards:')
|
|
custom_keyboards = CustomKeyboards()
|
|
for kb in keyboards:
|
|
kb_path = os.path.join(kbdir, kb["id"] + ".kmx")
|
|
logging.debug(f' removing {kb["id"]} ({kb_path})')
|
|
custom_keyboards.remove(kb_path)
|
|
else:
|
|
logging.info(f'Could not uninstall {where} keyboard "{packageID}" from list of keyboards')
|
|
|
|
else:
|
|
logging.info(f'Replacing {where} keyboard: "{packageID}"')
|
|
|
|
if not os.path.isdir(kbdir):
|
|
logging.info(f'Keyboard directory {kbdir} for "{packageID}" does not exist.')
|
|
logging.warning(f'Cannot uninstall non-existing {where} keyboard "{packageID}" for user {getpass.getuser()}')
|
|
|
|
_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(f'Finished uninstalling {where} keyboard: "{packageID}"')
|
|
return ''
|
|
|
|
|
|
def _uninstall_keyboards_from_ibus(keyboards, packageDir):
|
|
bus = get_ibus_bus()
|
|
ibusUtil = IbusUtil()
|
|
sources = ibusUtil.read_preload_engines()
|
|
if not sources:
|
|
return
|
|
|
|
# uninstall all specified keyboards for all languages
|
|
for kb in keyboards:
|
|
# keyboard ids are similar to `km:/path/to/keyman/khmer_angkor/khmer_angkor.kmx`
|
|
match_id = ":%s" % get_ibus_keyboard_id(kb, packageDir, ignore_language=True)
|
|
toRemove = [id for id in sources if id.endswith(match_id)]
|
|
for val in toRemove:
|
|
sources.remove(val)
|
|
|
|
ibusUtil.write_preload_engines(bus, sources)
|
|
restart_ibus(bus)
|
|
|
|
|
|
def _uninstall_keyboards_from_gnome(keyboards, packageDir):
|
|
gnomeKeyboardsUtil = GnomeKeyboardsUtil()
|
|
sources = gnomeKeyboardsUtil.read_input_sources()
|
|
|
|
# uninstall all kmx for all languages
|
|
for kb in keyboards:
|
|
ibus_keyboard_id = get_ibus_keyboard_id(kb, packageDir)
|
|
_tuple = ('ibus', ibus_keyboard_id)
|
|
if _tuple in sources:
|
|
sources.remove(_tuple)
|
|
|
|
match_id = ":%s" % get_ibus_keyboard_id(kb, packageDir, ignore_language=True)
|
|
toRemove = []
|
|
for (type, id) in sources:
|
|
if type == 'ibus' and id.endswith(match_id):
|
|
toRemove.append((type, id))
|
|
|
|
for val in toRemove:
|
|
sources.remove(val)
|
|
|
|
gnomeKeyboardsUtil.write_input_sources(sources)
|
|
|
|
|
|
def _uninstall_keyboards_from_fcitx5():
|
|
return _('Please use fcitx5-configtool to remove the keyboard from the group')
|
|
|
|
|
|
def uninstall_kmp(packageID, sharedarea=False, removeLanguages=True):
|
|
"""
|
|
Uninstall a Keyman keyboard package
|
|
|
|
Args:
|
|
packageID (str): Keyboard package ID
|
|
sharedarea (boolean): whether to uninstall from shared /usr/local or ~/.local
|
|
removeLanguages (boolean): if True also uninstall the languages associated with
|
|
the keyboard, otherwise only remove keyboard (i.e. in preparation for
|
|
replacing the keyboard with a newer version)
|
|
"""
|
|
if sharedarea:
|
|
msg = _uninstall_kmp_common(InstallLocation.Shared, packageID, removeLanguages)
|
|
else:
|
|
msg = _uninstall_kmp_common(InstallLocation.User, packageID, removeLanguages)
|
|
|
|
get_keyman_config_service().keyboard_list_changed()
|
|
return msg
|