mirror of
https://github.com/keymanapp/keyman.git
synced 2026-10-07 22:47:29 +00:00
chore(linux): Code cleanup
Some reformatting.
This commit is contained in:
parent
50f41ba069
commit
0944d83f97
10 changed files with 93 additions and 71 deletions
|
|
@ -12,16 +12,19 @@ with open('../../../resources/standards-data/langtags/langtags.json') as file:
|
|||
# The data comes from `resources/standards-data/langtag/langtags.json`.
|
||||
|
||||
class LangTagsMap():
|
||||
@staticmethod
|
||||
def lookupLangTags(language):
|
||||
if language in LangTagsMap.__langTags:
|
||||
return LangTagsMap.__langTags[language]
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def lookupAllTags(language):
|
||||
if language in LangTagsMap.__allTags:
|
||||
return LangTagsMap.__allTags[language]
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def translateISO6393ToBCP47(code):
|
||||
if code in LangTagsMap.__map3To2:
|
||||
return LangTagsMap.__map3To2[code]
|
||||
|
|
@ -41,8 +44,8 @@ class LangTagsMap():
|
|||
if lang['tag'] != lang['iso639_3']:
|
||||
if len(lang['tag']) < 3:
|
||||
map3To2.append("'%s': '%s'" % (lang['iso639_3'], lang['tag']))
|
||||
langTags.append(
|
||||
"'%s': {'full': '%s', 'region': '%s', 'script': '%s', 'suppress': %s}" % (lang['tag'], lang['full'], region, script, suppress))
|
||||
langTags.append("'%s': {'full': '%s', 'region': '%s', 'script': '%s', 'suppress': %s}" % (
|
||||
lang['tag'], lang['full'], region, script, suppress))
|
||||
allTags.append("'%s': '%s'" % (lang['tag'], lang['tag']))
|
||||
if lang['tag'] != lang['full']:
|
||||
allTags.append("'%s': '%s'" % (lang['full'], lang['tag']))
|
||||
|
|
@ -51,9 +54,9 @@ class LangTagsMap():
|
|||
if tag != lang['full'] and tag != lang['tag']:
|
||||
allTags.append("'%s': '%s'" % (tag, lang['tag']))
|
||||
|
||||
langTagsString = ',\n '.join(map(str, langTags))
|
||||
allTagsString = ',\n '.join(allTags)
|
||||
map3To2String = ',\n '.join(map3To2)
|
||||
outputFile.write(" __langTags = {\n %s }\n\n" % langTagsString)
|
||||
outputFile.write(" __allTags = { %s }\n\n" % allTagsString)
|
||||
outputFile.write(" __map3To2 = { %s }\n" % map3To2String)
|
||||
langTagsString = ',\n '.join(map(str, langTags))
|
||||
allTagsString = ',\n '.join(allTags)
|
||||
map3To2String = ',\n '.join(map3To2)
|
||||
outputFile.write(" __langTags = {\n %s}\n\n" % langTagsString)
|
||||
outputFile.write(" __allTags = {\n %s}\n\n" % allTagsString)
|
||||
outputFile.write(" __map3To2 = {\n %s}\n" % map3To2String)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ except ImportError:
|
|||
|
||||
|
||||
class CanonicalLanguageCodeUtils():
|
||||
@staticmethod
|
||||
def findBestTag(tag, addRegion, addScriptIfNotSuppressed):
|
||||
"""
|
||||
Find a language code with appropriate script and region subtags</summary>
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class DownloadKmpWindow(Gtk.Dialog):
|
|||
self.resize(800, 450)
|
||||
self.show_all()
|
||||
|
||||
def _process_kmp(self, url, downloadfile):
|
||||
def _process_kmp(self, url, downloadfile: str):
|
||||
logging.info("Downloading kmp file to %s", downloadfile)
|
||||
if download_kmp_file(url, downloadfile):
|
||||
logging.info("File downloaded")
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ class GnomeKeyboardsUtil():
|
|||
def read_input_sources(self):
|
||||
sources = self.input_sources.get('sources')
|
||||
logging.debug('read sources: %s', sources)
|
||||
if sources is None:
|
||||
return []
|
||||
return sources
|
||||
|
||||
def write_input_sources(self, sources):
|
||||
|
|
|
|||
|
|
@ -90,9 +90,9 @@ class GSettings():
|
|||
if self.is_sudo:
|
||||
variant = str(value)
|
||||
subprocess.run(
|
||||
['sudo', '-H', '-u', os.environ.get('SUDO_USER'),
|
||||
'DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%s/bus' % os.environ.get('SUDO_UID'),
|
||||
'gsettings', 'set', self.schema_id, key, variant])
|
||||
['sudo', '-H', '-u', os.environ.get('SUDO_USER'),
|
||||
'DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%s/bus' % os.environ.get('SUDO_UID'),
|
||||
'gsettings', 'set', self.schema_id, key, variant])
|
||||
else:
|
||||
variant = self._convert_array_to_variant(value, type)
|
||||
self.schema.set_value(key, variant)
|
||||
|
|
|
|||
|
|
@ -79,17 +79,17 @@ class InstallKmp():
|
|||
online (bool, default=False): whether to attempt to get online keyboard data
|
||||
"""
|
||||
self._check_keyman_dir(
|
||||
'/usr/local/share',
|
||||
_("You do not have permissions to install the keyboard files to the shared area "
|
||||
"/usr/local/share/keyman"))
|
||||
'/usr/local/share',
|
||||
_("You do not have permissions to install the keyboard files to the shared area "
|
||||
"/usr/local/share/keyman"))
|
||||
self._check_keyman_dir(
|
||||
'/usr/local/share/doc',
|
||||
_("You do not have permissions to install the documentation to the shared "
|
||||
"documentation area /usr/local/share/doc/keyman"))
|
||||
'/usr/local/share/doc',
|
||||
_("You do not have permissions to install the documentation to the shared "
|
||||
"documentation area /usr/local/share/doc/keyman"))
|
||||
self._check_keyman_dir(
|
||||
'/usr/local/share/fonts',
|
||||
_("You do not have permissions to install the font files to the shared font area "
|
||||
"/usr/local/share/fonts"))
|
||||
'/usr/local/share/fonts',
|
||||
_("You do not have permissions to install the font files to the shared font area "
|
||||
"/usr/local/share/fonts"))
|
||||
|
||||
return self._install_kmp(inputfile, online, language, InstallLocation.Shared)
|
||||
|
||||
|
|
@ -128,7 +128,7 @@ class InstallKmp():
|
|||
inputfile, fileVersion)
|
||||
rmtree(self.packageDir)
|
||||
message = _("{packageFile} requires Keyman {keymanVersion} or higher").format(
|
||||
packageFile=inputfile, keymanVersion=fileVersion)
|
||||
packageFile=inputfile, keymanVersion=fileVersion)
|
||||
raise InstallError(InstallStatus.Abort, message)
|
||||
if keyboards:
|
||||
logging.info("Installing %s", secure_lookup(info, 'name', 'description'))
|
||||
|
|
@ -138,6 +138,9 @@ class InstallKmp():
|
|||
if kb['id'] != self.packageID:
|
||||
process_keyboard_data(kb['id'], self.packageDir)
|
||||
|
||||
if files is None:
|
||||
return self.install_keyboards(keyboards, self.packageDir, language)
|
||||
|
||||
for f in files:
|
||||
fpath = os.path.join(self.packageDir, f['name'])
|
||||
ftype = f['type']
|
||||
|
|
@ -188,7 +191,7 @@ class InstallKmp():
|
|||
logging.info(o)
|
||||
rmtree(self.packageDir)
|
||||
message = _("No kmp.json or kmp.inf found in {packageFile}").format(
|
||||
packageFile=inputfile)
|
||||
packageFile=inputfile)
|
||||
raise InstallError(InstallStatus.Abort, message)
|
||||
|
||||
def _safeMakeDirs(self, dir):
|
||||
|
|
@ -274,7 +277,7 @@ def extract_kmp(kmpfile, directory):
|
|||
zip_ref.extractall(directory)
|
||||
|
||||
|
||||
def process_keyboard_data(keyboardID, packageDir):
|
||||
def process_keyboard_data(keyboardID, packageDir) -> None:
|
||||
kbdata = get_keyboard_data(keyboardID)
|
||||
if kbdata:
|
||||
if not os.path.isdir(packageDir) and os.access(os.path.join(packageDir, os.pardir), os.X_OK | os.W_OK):
|
||||
|
|
@ -304,6 +307,8 @@ def install_kmp(inputfile, online=False, sharedarea=False, language=None):
|
|||
inputfile (str): path to kmp file
|
||||
online(bool, default=False): whether to attempt to get online keyboard data
|
||||
sharedarea(bool, default=False): whether install kmp to shared area or user directory
|
||||
language(str, default=None): language to install keyboard for
|
||||
has_ui(bool, default=True): whether we're displaying a window or running UI less from the command line
|
||||
"""
|
||||
if sharedarea:
|
||||
return InstallKmp().install_kmp_shared(inputfile, online, language)
|
||||
|
|
|
|||
|
|
@ -68,8 +68,8 @@ class InstallKmpWindow(Gtk.Dialog):
|
|||
if not keyboards:
|
||||
# Likely not a keyboard .kmp file
|
||||
logging.info("%s is not a Keyman keyboard package" % kmpfile)
|
||||
dialog = Gtk.MessageDialog(viewkmp, 0, Gtk.MessageType.ERROR, Gtk.ButtonsType.OK,
|
||||
_("The file '{kmpfile}' is not a Keyman keyboard package!").format(kmpfile=kmpfile))
|
||||
dialog = Gtk.MessageDialog(viewkmp, 0, Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, _(
|
||||
"The file '{kmpfile}' is not a Keyman keyboard package!").format(kmpfile=kmpfile))
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
self.checkcontinue = False
|
||||
|
|
@ -83,11 +83,11 @@ class InstallKmpWindow(Gtk.Dialog):
|
|||
if installed_kmp_ver and secure_lookup(info, 'version', 'description'):
|
||||
if secure_lookup(info, 'version', 'description') == installed_kmp_ver:
|
||||
dialog = Gtk.MessageDialog(
|
||||
viewkmp, 0, Gtk.MessageType.QUESTION,
|
||||
Gtk.ButtonsType.YES_NO, _("Keyboard is installed already"))
|
||||
viewkmp, 0, Gtk.MessageType.QUESTION,
|
||||
Gtk.ButtonsType.YES_NO, _("Keyboard is installed already"))
|
||||
dialog.format_secondary_text(
|
||||
_("The {name} keyboard is already installed at version {version}. "
|
||||
"Do you want to uninstall then reinstall it?")
|
||||
_("The {name} keyboard is already installed at version {version}. "
|
||||
"Do you want to uninstall then reinstall it?")
|
||||
.format(name=self.kbname, version=installed_kmp_ver))
|
||||
response = dialog.run()
|
||||
dialog.destroy()
|
||||
|
|
@ -102,10 +102,11 @@ class InstallKmpWindow(Gtk.Dialog):
|
|||
try:
|
||||
logging.info("package version %s", secure_lookup(info, 'version', 'description'))
|
||||
logging.info("installed kmp version %s", installed_kmp_ver)
|
||||
if StrictVersion(secure_lookup(info, 'version', 'description')) <= StrictVersion(installed_kmp_ver):
|
||||
if StrictVersion(secure_lookup(info, 'version',
|
||||
'description')) <= StrictVersion(installed_kmp_ver):
|
||||
dialog = Gtk.MessageDialog(
|
||||
viewkmp, 0, Gtk.MessageType.QUESTION,
|
||||
Gtk.ButtonsType.YES_NO, _("Keyboard is installed already"))
|
||||
viewkmp, 0, Gtk.MessageType.QUESTION,
|
||||
Gtk.ButtonsType.YES_NO, _("Keyboard is installed already"))
|
||||
dialog.format_secondary_text(
|
||||
_("The {name} keyboard is already installed with a newer version {installedversion}. "
|
||||
"Do you want to uninstall it and install the older version {version}?")
|
||||
|
|
@ -186,14 +187,16 @@ class InstallKmpWindow(Gtk.Dialog):
|
|||
grid.attach_next_to(label3, prevlabel, Gtk.PositionType.BOTTOM, 1, 1)
|
||||
prevlabel = label3
|
||||
label = Gtk.Label()
|
||||
if secure_lookup(info, 'version', 'description'):
|
||||
label.set_text(secure_lookup(info, 'version', 'description'))
|
||||
description = secure_lookup(info, 'version', 'description')
|
||||
if description:
|
||||
label.set_text(description)
|
||||
label.set_halign(Gtk.Align.START)
|
||||
label.set_selectable(True)
|
||||
grid.attach_next_to(label, label3, Gtk.PositionType.RIGHT, 1, 1)
|
||||
|
||||
if secure_lookup(info, 'author'):
|
||||
author = info['author']
|
||||
author = secure_lookup(info, 'author')
|
||||
if author:
|
||||
author = author
|
||||
label4 = Gtk.Label()
|
||||
label4.set_text(_("Author: "))
|
||||
label4.set_halign(Gtk.Align.END)
|
||||
|
|
@ -202,8 +205,8 @@ class InstallKmpWindow(Gtk.Dialog):
|
|||
label = Gtk.Label()
|
||||
if secure_lookup(author, 'url') and secure_lookup(author, 'description'):
|
||||
label.set_markup(
|
||||
"<a href=\"" + author['url'] + "\" title=\"" +
|
||||
author['url'] + "\">" + author['description'] + "</a>")
|
||||
"<a href=\"" + author['url'] + "\" title=\"" +
|
||||
author['url'] + "\">" + author['description'] + "</a>")
|
||||
elif secure_lookup(author, 'description'):
|
||||
label.set_text(author['description'])
|
||||
label.set_halign(Gtk.Align.START)
|
||||
|
|
@ -218,10 +221,10 @@ class InstallKmpWindow(Gtk.Dialog):
|
|||
grid.attach_next_to(label5, prevlabel, Gtk.PositionType.BOTTOM, 1, 1)
|
||||
prevlabel = label5
|
||||
label = Gtk.Label()
|
||||
if secure_lookup(info, 'website', 'description'):
|
||||
website_description = secure_lookup(info, 'website', 'description')
|
||||
if website_description:
|
||||
label.set_markup(
|
||||
"<a href=\"" + secure_lookup(info, 'website', 'description') + "\">" +
|
||||
secure_lookup(info, 'website', 'description') + "</a>")
|
||||
"<a href=\"" + website_description + "\">" + website_description + "</a>")
|
||||
label.set_halign(Gtk.Align.START)
|
||||
label.set_selectable(True)
|
||||
grid.attach_next_to(label, label5, Gtk.PositionType.RIGHT, 1, 1)
|
||||
|
|
@ -232,8 +235,9 @@ class InstallKmpWindow(Gtk.Dialog):
|
|||
label6.set_halign(Gtk.Align.END)
|
||||
grid.attach_next_to(label6, prevlabel, Gtk.PositionType.BOTTOM, 1, 1)
|
||||
label = Gtk.Label()
|
||||
if secure_lookup(info, 'copyright', 'description'):
|
||||
label.set_text(secure_lookup(info, 'copyright', 'description'))
|
||||
copyright_description = secure_lookup(info, 'copyright', 'description')
|
||||
if copyright_description:
|
||||
label.set_text(copyright_description)
|
||||
label.set_halign(Gtk.Align.START)
|
||||
label.set_selectable(True)
|
||||
grid.attach_next_to(label, label6, Gtk.PositionType.RIGHT, 1, 1)
|
||||
|
|
@ -242,8 +246,9 @@ class InstallKmpWindow(Gtk.Dialog):
|
|||
webview = WebKit2.WebView()
|
||||
webview.connect("decide-policy", self.doc_policy)
|
||||
|
||||
if secure_lookup(options, 'readmeFile'):
|
||||
self.readme = options['readmeFile']
|
||||
readmeFile = secure_lookup(options, 'readmeFile')
|
||||
if readmeFile:
|
||||
self.readme = readmeFile
|
||||
else:
|
||||
self.readme = "noreadme"
|
||||
readme_file = os.path.join(tmpdirname, self.readme)
|
||||
|
|
@ -323,8 +328,8 @@ class InstallKmpWindow(Gtk.Dialog):
|
|||
# because for fcitx they will need to take extra steps to complete
|
||||
# installation themselves.
|
||||
dialog = Gtk.MessageDialog(
|
||||
self, 0, Gtk.MessageType.INFO,
|
||||
Gtk.ButtonsType.OK, result)
|
||||
self, 0, Gtk.MessageType.INFO,
|
||||
Gtk.ButtonsType.OK, result)
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
if is_fcitx_running():
|
||||
|
|
@ -350,12 +355,12 @@ class InstallKmpWindow(Gtk.Dialog):
|
|||
except InstallError as e:
|
||||
if e.status == InstallStatus.Abort:
|
||||
message = _("Keyboard {name} could not be installed.").format(name=self.kbname) \
|
||||
+ "\n\n" + _("Error Message:") + "\n %s" % (e.message)
|
||||
+ "\n\n" + _("Error Message:") + "\n %s" % (e.message)
|
||||
logging.error(message)
|
||||
message_type = Gtk.MessageType.ERROR
|
||||
else:
|
||||
message = _("Keyboard {name} could not be installed.").format(name=self.kbname) \
|
||||
+ "\n\n" + _("Warning Message:") + "\n %s" % (e.message)
|
||||
+ "\n\n" + _("Warning Message:") + "\n %s" % (e.message)
|
||||
logging.warning(message)
|
||||
message_type = Gtk.MessageType.WARNING
|
||||
dialog = Gtk.MessageDialog(
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ from keyman_config.ibus_util import uninstall_from_ibus, get_ibus_bus, restart_i
|
|||
from keyman_config.gnome_keyboards_util import GnomeKeyboardsUtil, get_ibus_keyboard_id, is_gnome_shell
|
||||
|
||||
|
||||
def delete_dir(dir):
|
||||
def delete_dir(dir: str) -> bool:
|
||||
if not os.path.isdir(dir):
|
||||
logging.error("%s is not a directory", dir)
|
||||
return False
|
||||
|
|
@ -40,12 +40,12 @@ def uninstall_kmp_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
|
||||
logging.error(
|
||||
"You do not have permissions to uninstall the keyboard files. You need to run this with `sudo`")
|
||||
"You do not have permissions to uninstall the keyboard files. You need to run this with `sudo`")
|
||||
exit(3)
|
||||
if os.path.isdir(kbdocdir):
|
||||
if not os.access(kbdocdir, os.X_OK | os.W_OK): # Check for write access of keyman doc dir
|
||||
logging.error(
|
||||
"You do not have permissions to uninstall the documentation. You need to run this with `sudo`")
|
||||
"You do not have permissions to uninstall the documentation. You need to run this with `sudo`")
|
||||
exit(3)
|
||||
delete_dir(kbdocdir)
|
||||
logging.info("Removed documentation directory: %s", kbdocdir)
|
||||
|
|
@ -54,7 +54,7 @@ def uninstall_kmp_shared(packageID):
|
|||
if os.path.isdir(kbfontdir):
|
||||
if not os.access(kbfontdir, os.X_OK | os.W_OK): # Check for write access of keyman fonts
|
||||
logging.error(
|
||||
"You do not have permissions to uninstall the font files. You need to run this with `sudo`")
|
||||
"You do not have permissions to uninstall the font files. You need to run this with `sudo`")
|
||||
exit(3)
|
||||
delete_dir(kbfontdir)
|
||||
logging.info("Removed font directory: %s", kbfontdir)
|
||||
|
|
|
|||
|
|
@ -59,8 +59,8 @@ class ViewInstalledWindowBase(Gtk.Window):
|
|||
def on_installfile_clicked(self, button):
|
||||
logging.debug("Install from file clicked")
|
||||
dlg = Gtk.FileChooserDialog(
|
||||
_("Choose a kmp file..."), self, Gtk.FileChooserAction.OPEN,
|
||||
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
|
||||
_("Choose a kmp file..."), self, Gtk.FileChooserAction.OPEN,
|
||||
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
|
||||
dlg.resize(640, 480)
|
||||
filter_text = Gtk.FileFilter()
|
||||
# i18n: file type in file selection dialog
|
||||
|
|
|
|||
|
|
@ -1,21 +1,22 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import argparse
|
||||
from distutils.version import StrictVersion
|
||||
import logging
|
||||
import sys
|
||||
import os
|
||||
from keyman_config import __version__, KeymanApiUrl, secure_lookup
|
||||
from keyman_config.uninstall_kmp import uninstall_kmp
|
||||
|
||||
import datetime
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
from distutils.version import StrictVersion
|
||||
from zipfile import is_zipfile
|
||||
|
||||
from keyman_config import KeymanApiUrl, __version__, secure_lookup
|
||||
from keyman_config.uninstall_kmp import uninstall_kmp
|
||||
|
||||
|
||||
def get_languages():
|
||||
import requests
|
||||
import requests_cache
|
||||
|
||||
from keyman_config.get_kmp import keyman_cache_dir
|
||||
|
||||
logging.info("Getting language list from search")
|
||||
|
|
@ -45,6 +46,9 @@ def get_languages():
|
|||
def get_keyboard_list():
|
||||
languages = get_languages()
|
||||
keyboards = []
|
||||
if not languages:
|
||||
return []
|
||||
|
||||
if "languages" in languages:
|
||||
for lang in languages["languages"]:
|
||||
if "keyboards" in lang:
|
||||
|
|
@ -82,8 +86,8 @@ def list_keyboards():
|
|||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Install a Keyman keyboard package, either a local .kmp file or specify a ' +
|
||||
'keyboard id to download and install')
|
||||
description='Install a Keyman keyboard package, either a local .kmp file or specify a ' +
|
||||
'keyboard id to download and install')
|
||||
parser.add_argument('-s', '--shared', action='store_true', help='Install to shared area /usr/local')
|
||||
parser.add_argument('-f', '--file', metavar='KMPFILE', help='Keyman kmp file')
|
||||
parser.add_argument('-p', '--package', metavar='PACKAGE', help='Keyman package id')
|
||||
|
|
@ -102,13 +106,15 @@ def main():
|
|||
if args.package and args.file:
|
||||
parser.print_usage()
|
||||
logging.error(
|
||||
"km-package-install: error: too many arguments: either install a local kmp file or " +
|
||||
"specify a keyboard id to download and install.")
|
||||
"km-package-install: error: too many arguments: either install a local kmp file or " +
|
||||
"specify a keyboard id to download and install.")
|
||||
sys.exit(2)
|
||||
|
||||
from keyman_config.install_kmp import install_kmp, InstallError, InstallStatus
|
||||
from keyman_config.get_kmp import (get_keyboard_data, get_kmp,
|
||||
keyman_cache_dir)
|
||||
from keyman_config.install_kmp import (InstallError, InstallStatus,
|
||||
install_kmp)
|
||||
from keyman_config.list_installed_kmp import get_kmp_version
|
||||
from keyman_config.get_kmp import get_keyboard_data, get_kmp, keyman_cache_dir
|
||||
|
||||
if os.path.exists(os.path.join(keyman_cache_dir(), 'kmpdirlist')):
|
||||
os.remove(os.path.join(keyman_cache_dir(), 'kmpdirlist'))
|
||||
|
|
@ -165,8 +171,8 @@ def main():
|
|||
else:
|
||||
parser.print_usage()
|
||||
logging.error(
|
||||
"km-package-install: error: no arguments: either install a local kmp file " +
|
||||
"or specify a keyboard package id to download and install.")
|
||||
"km-package-install: error: no arguments: either install a local kmp file " +
|
||||
"or specify a keyboard package id to download and install.")
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue